news 2025/12/31 20:37:26

Java集合框架全面详解,从小白到精通,收藏这篇就够了

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java集合框架全面详解,从小白到精通,收藏这篇就够了

1. 集合框架概述

1.1 什么是集合框架?

集合框架是一个统一的架构,用于表示和操作集合,使集合能够独立于其实现细节进行操作。Java集合框架提供了一系列接口和类,用于存储、检索、操作和传输数据对象。

1.2 为什么需要集合框架?

在Java早期版本中,Java提供了有限的几个类用于数据存储和操作(如Vector、Hashtable等),但这些类缺乏统一的设计理念。Java 1.2引入集合框架,目的是:

1.3 集合框架的组成部分

Java集合框架主要由三部分组成:

  1. 接口(Interfaces):表示集合的抽象数据类型。允许集合独立于其实现细节进行操作。
  2. 实现类(Implementations):接口的具体实现,即可重用的数据结构。
  3. 算法(Algorithms):对实现了集合接口的对象进行操作的方法,如搜索和排序。

2. 核心接口

Java集合框架的核心接口构成了框架的基础。以下是最重要的接口:

2.1 Collection接口

Collection是集合层次结构的根接口,所有集合类都实现了这个接口。它提供了适用于所有集合的基本操作。

主要方法:

2.2 List接口

List是一个有序的Collection,用户可以通过索引访问元素,并且允许重复元素。

特点:

额外的主要方法:

2.3 Set接口

Set是一个不包含重复元素的Collection

特点:

Set接口没有在Collection接口之外添加新方法,只是改变了一些方法的行为语义。例如,add方法对于已存在的元素将返回false

2.4 Queue接口

Queue代表了先进先出(FIFO)的数据结构,除了基本的Collection操作外,还提供了额外的插入、提取和检查操作。

主要方法:

2.5 Deque接口

Deque(双端队列)是Queue的子接口,允许在两端进行插入和删除操作。

主要方法:

2.6 Map接口

Map虽然不是Collection的子接口,但也是集合框架的一部分。Map将键映射到值,不能包含重复的键,每个键最多映射到一个值。

主要方法:

3. 实现类

Java集合框架提供了许多实现类,每个类都有其特定的特性和适用场景。

3.1 List实现
3.1.1 ArrayList

ArrayList是基于数组实现的List,提供了快速的随机访问,但插入和删除元素的速度较慢。

特点:

示例:

List<String> arrayList = new ArrayList<>(); arrayList.add("Java"); arrayList.add("Python"); arrayList.add("C++"); System.out.println(arrayList.get(1)); // 输出: Python
3.1.2 LinkedList

LinkedList是基于双向链表实现的List,提供了快速的插入和删除操作,但随机访问元素的速度较慢。

特点:

示例:

LinkedList<String> linkedList = new LinkedList<>(); linkedList.add("Java"); linkedList.add("Python"); linkedList.addFirst("C++"); // 在开头添加元素 linkedList.addLast("JavaScript"); // 在末尾添加元素 System.out.println(linkedList); // 输出: [C++, Java, Python, JavaScript]
3.1.3 Vector

Vector是早期Java版本中的集合类,现在已经被重新设计为实现List接口。它类似于ArrayList,但所有方法都是同步的。

特点:

示例:

Vector<String> vector = new Vector<>(); vector.add("Java"); vector.add("Python"); vector.add("C++"); System.out.println(vector.elementAt(1)); // 输出: Python
3.1.4 Stack

Stack继承自Vector,实现了标准的后进先出(LIFO)栈。

特点:

主要方法:

示例:

Stack<String> stack = new Stack<>(); stack.push("Java"); stack.push("Python"); stack.push("C++"); System.out.println(stack.pop()); // 输出: C++ System.out.println(stack.peek()); // 输出: Python
3.2 Set实现
3.2.1 HashSet

HashSet是基于哈希表实现的Set,它不保证集合的迭代顺序,允许使用null元素。

特点:

示例:

Set<String> hashSet = new HashSet<>(); hashSet.add("Java"); hashSet.add("Python"); hashSet.add("Java"); // 重复元素,不会被添加 System.out.println(hashSet); // 输出顺序可能不同
3.2.2 LinkedHashSet

LinkedHashSet是HashSet的子类,它维护了一个双向链表,记录了元素的插入顺序。

特点:

示例:

Set<String> linkedHashSet = new LinkedHashSet<>(); linkedHashSet.add("Java"); linkedHashSet.add("Python"); linkedHashSet.add("C++"); System.out.println(linkedHashSet); // 输出: [Java, Python, C++]
3.2.3 TreeSet

TreeSet是基于红黑树实现的NavigableSet,它按照元素的自然顺序或者指定的比较器排序。

特点:

示例:

TreeSet<String> treeSet = new TreeSet<>(); treeSet.add("Java"); treeSet.add("Python"); treeSet.add("C++"); System.out.println(treeSet); // 输出: [C++, Java, Python](按字母顺序) // 使用比较器 TreeSet<String> customTreeSet = new TreeSet<>(Comparator.reverseOrder()); customTreeSet.add("Java"); customTreeSet.add("Python"); customTreeSet.add("C++"); System.out.println(customTreeSet); // 输出: [Python, Java, C++](按字母逆序)
3.3 Queue实现
3.3.1 PriorityQueue

PriorityQueue是基于优先级堆实现的队列,元素按照自然顺序或者指定的比较器排序。

特点:

示例:

PriorityQueue<Integer> priorityQueue = new PriorityQueue<>(); priorityQueue.add(5); priorityQueue.add(1); priorityQueue.add(3); System.out.println(priorityQueue.poll()); // 输出: 1 System.out.println(priorityQueue.poll()); // 输出: 3
3.3.2 ArrayDeque

ArrayDeque是基于可调整大小的数组实现的双端队列,它作为栈和队列都比Stack和LinkedList更高效。

特点:

示例:

// 作为队列使用 Queue<String> queue = new ArrayDeque<>(); queue.offer("Java"); queue.offer("Python"); queue.offer("C++"); System.out.println(queue.poll()); // 输出: Java // 作为栈使用 Deque<String> stack = new ArrayDeque<>(); stack.push("Java"); stack.push("Python"); stack.push("C++"); System.out.println(stack.pop()); // 输出: C++
3.4 Map实现
3.4.1 HashMap

HashMap是基于哈希表实现的Map,它不保证映射的顺序,允许使用null键和null值。

特点:

示例:

Map<String, Integer> hashMap = new HashMap<>(); hashMap.put("Java", 1995); hashMap.put("Python", 1991); hashMap.put("C++", 1983); System.out.println(hashMap.get("Java")); // 输出: 1995
3.4.2 LinkedHashMap

LinkedHashMap是HashMap的子类,它维护了一个双向链表,可以记录元素的插入顺序或访问顺序。

特点:

示例:

// 按插入顺序 Map<String, Integer> linkedHashMap = new LinkedHashMap<>(); linkedHashMap.put("Java", 1995); linkedHashMap.put("Python", 1991); linkedHashMap.put("C++", 1983); System.out.println(linkedHashMap); // 输出保持插入顺序 // 按访问顺序(LRU缓存) Map<String, Integer> lruCache = new LinkedHashMap<>(16, 0.75f, true); lruCache.put("Java", 1995); lruCache.put("Python", 1991); lruCache.put("C++", 1983); lruCache.get("Java"); // 访问Java System.out.println(lruCache); // Java将移到最后(最近访问)
3.4.3 TreeMap

TreeMap是基于红黑树实现的NavigableMap,它按照键的自然顺序或者指定的比较器排序。

特点:

示例:

TreeMap<String, Integer> treeMap = new TreeMap<>(); treeMap.put("Java", 1995); treeMap.put("Python", 1991); treeMap.put("C++", 1983); System.out.println(treeMap); // 输出按键的字母顺序排序 // 使用比较器 TreeMap<String, Integer> customTreeMap = new TreeMap<>(Comparator.reverseOrder()); customTreeMap.put("Java", 1995); customTreeMap.put("Python", 1991); customTreeMap.put("C++", 1983); System.out.println(customTreeMap); // 输出按键的字母逆序排序
3.4.4 Hashtable

Hashtable是早期Java版本中的类,现在已经被重新设计为实现Map接口。它类似于HashMap,但所有方法都是同步的,并且不允许null键或值。

特点:

示例:

Hashtable<String, Integer> hashtable = new Hashtable<>(); hashtable.put("Java", 1995); hashtable.put("Python", 1991); hashtable.put("C++", 1983); System.out.println(hashtable.get("Java")); // 输出: 1995
3.4.5 Properties

PropertiesHashtable的子类,用于存储字符串键值对。它通常用于读取和写入配置文件。

特点:

示例:

Properties properties = new Properties(); properties.setProperty("username", "admin"); properties.setProperty("password", "123456"); System.out.println(properties.getProperty("username")); // 输出: admin System.out.println(properties.getProperty("email", "default@example.com")); // 输出默认值: default@example.com // 保存到文件 try (FileOutputStream out = new FileOutputStream("config.properties")) { properties.store(out, "Configuration"); } catch (IOException e) { e.printStackTrace(); } // 从文件加载 Properties loadedProps = new Properties(); try (FileInputStream in = new FileInputStream("config.properties")) { loadedProps.load(in); System.out.println(loadedProps.getProperty("username")); // 输出: admin } catch (IOException e) { e.printStackTrace(); }

4. 工具类

Java集合框架提供了两个主要的工具类,用于对集合和数组进行操作。

4.1 Collections类

Collections类提供了一系列静态方法,用于操作和返回集合。

主要方法:

示例:

List<Integer> numbers = new ArrayList<>(); numbers.add(3); numbers.add(1); numbers.add(2); // 排序 Collections.sort(numbers); System.out.println(numbers); // 输出: [1, 2, 3] // 二分查找 int index = Collections.binarySearch(numbers, 2); System.out.println(index); // 输出: 1 // 反转 Collections.reverse(numbers); System.out.println(numbers); // 输出: [3, 2, 1] // 打乱 Collections.shuffle(numbers); System.out.println(numbers); // 输出随机顺序 // 不可修改的集合 List<Integer> unmodifiableList = Collections.unmodifiableList(numbers); try { unmodifiableList.add(4); // 抛出UnsupportedOperationException } catch (UnsupportedOperationException e) { System.out.println("Cannot modify unmodifiable list"); } // 同步集合 List<Integer> synchronizedList = Collections.synchronizedList(numbers); // 单例集合 Set<Integer> singletonSet = Collections.singleton(1);
4.2 Arrays类

Arrays类提供了一系列静态方法,用于操作数组。

主要方法:

示例:

Integer[] numbers = {3, 1, 2}; // 排序 Arrays.sort(numbers); System.out.println(Arrays.toString(numbers)); // 输出: [1, 2, 3] // 二分查找 int index = Arrays.binarySearch(numbers, 2); System.out.println(index); // 输出: 1 // 填充 Arrays.fill(numbers, 0); System.out.println(Arrays.toString(numbers)); // 输出: [0, 0, 0] // 复制 Integer[] original = {1, 2, 3}; Integer[] copy = Arrays.copyOf(original, 5); System.out.println(Arrays.toString(copy)); // 输出: [1, 2, 3, null, null] // 转换为List List<Integer> list = Arrays.asList(1, 2, 3); System.out.println(list); // 输出: [1, 2, 3] // 注意: 返回的列表是固定大小的,不能添加或删除元素 // 多维数组 Integer[][] matrix = {{1, 2}, {3, 4}}; System.out.println(Arrays.deepToString(matrix)); // 输出: [[1, 2], [3, 4]]

5. 特殊集合

5.1 Legacy集合

Legacy集合是Java 1.2之前就存在的集合类,它们已经被重新设计为适应集合框架。

包括:

尽管这些类现在都是集合框架的一部分,但它们的设计与框架中的其他部分不太协调。一般情况下,应该使用它们的替代品(ArrayList、HashMap等)。

5.2 并发集合

Java提供了许多线程安全的集合实现,它们位于java.util.concurrent包中。

主要类:

示例:

// ConcurrentHashMap Map<String, Integer> concurrentMap = new ConcurrentHashMap<>(); concurrentMap.put("Java", 1995); concurrentMap.put("Python", 1991); System.out.println(concurrentMap.get("Java")); // 输出: 1995 // CopyOnWriteArrayList List<String> copyOnWriteList = new CopyOnWriteArrayList<>(); copyOnWriteList.add("Java"); copyOnWriteList.add("Python"); // 适合多线程读操作多,写操作少的场景 // ArrayBlockingQueue BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(10); // 容量为10 blockingQueue.put("Java"); // 如果队列已满,put方法会阻塞 String item = blockingQueue.take(); // 如果队列为空,take方法会阻塞 System.out.println(item); // 输出: Java
5.3 不可变集合

不可变集合是指创建后不能修改的集合。Java提供了几种方式来创建不可变集合:

  1. Collections工具类

  2. List.of()、Set.of()和Map.of()方法(Java 9+)

  3. Guava库的ImmutableXXX类

示例:

// 使用Collections List<String> modifiableList = new ArrayList<>(); modifiableList.add("Java"); modifiableList.add("Python"); List<String> unmodifiableList = Collections.unmodifiableList(modifiableList); // 使用Java 9+的工厂方法 List<String> immutableList = List.of("Java", "Python", "C++"); Set<String> immutableSet = Set.of("Java", "Python", "C++"); Map<String, Integer> immutableMap = Map.of("Java", 1995, "Python", 1991, "C++", 1983); // 尝试修改不可变集合会抛出UnsupportedOperationException try { immutableList.add("Go"); } catch (UnsupportedOperationException e) { System.out.println("Cannot modify immutable list"); }

6. 集合操作

6.1 遍历集合

Java提供了多种方式来遍历集合:

  1. 使用Iterator
List<String> list = new ArrayList<>(); list.add("Java"); list.add("Python"); list.add("C++"); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String element = iterator.next(); System.out.println(element); // 安全地删除元素 if (element.equals("Python")) { iterator.remove(); } }
  1. 使用for-each循环
for (String element : list) { System.out.println(element); // 注意: 在for-each循环中不能安全地修改集合 }
  1. 使用索引(仅适用于List)
for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); }
  1. 使用forEach方法(Java 8+)
list.forEach(element -> System.out.println(element)); // 或使用方法引用 list.forEach(System.out::println);
  1. 使用Stream API(Java 8+)
list.stream() .filter(element -> element.startsWith("J")) .forEach(System.out::println);
6.2 排序集合
  1. 使用Collections.sort()
List<String> list = new ArrayList<>(); list.add("C++"); list.add("Python"); list.add("Java"); // 自然顺序排序 Collections.sort(list); System.out.println(list); // 输出: [C++, Java, Python] // 使用比较器排序 Collections.sort(list, Comparator.reverseOrder()); System.out.println(list); // 输出: [Python, Java, C++]
  1. 使用List.sort()(Java 8+)
// 自然顺序排序 list.sort(null); System.out.println(list); // 输出: [C++, Java, Python] // 使用比较器排序 list.sort(Comparator.reverseOrder()); System.out.println(list); // 输出: [Python, Java, C++]
  1. 使用TreeSet或TreeMap自动排序
Set<String> treeSet = new TreeSet<>(); treeSet.add("C++"); treeSet.add("Python"); treeSet.add("Java"); System.out.println(treeSet); // 输出: [C++, Java, Python]
  1. 使用Stream API排序(Java 8+)
List<String> sortedList = list.stream() .sorted() .collect(Collectors.toList()); System.out.println(sortedList); // 输出: [C++, Java, Python]
6.3 集合间的转换
  1. Collection转数组
List<String> list = new ArrayList<>(); list.add("Java"); list.add("Python"); // 转换为Object数组 Object[] objectArray = list.toArray(); // 转换为指定类型的数组 String[] stringArray = list.toArray(new String[0]); // 或使用Java 11+的新方法 String[] stringArray2 = list.toArray(String[]::new);
  1. 数组转Collection
String[] array = {"Java", "Python", "C++"}; // 使用Arrays.asList() - 返回固定大小的List List<String> list = Arrays.asList(array); // 使用new ArrayList<>(Arrays.asList()) - 返回可调整大小的List List<String> modifiableList = new ArrayList<>(Arrays.asList(array)); // 使用List.of() - 返回不可变List(Java 9+) List<String> immutableList = List.of(array); // 使用Stream API(Java 8+) List<String> streamList = Arrays.stream(array).collect(Collectors.toList()); Set<String> streamSet = Arrays.stream(array).collect(Collectors.toSet());
  1. Collection之间的转换
List<String> list = new ArrayList<>(); list.add("Java"); list.add("Python"); list.add("Java"); // 重复元素 // List转Set(移除重复元素) Set<String> set = new HashSet<>(list); System.out.println(set); // 输出: [Java, Python] // Set转List List<String> newList = new ArrayList<>(set); // 使用Stream API List<String> streamList = set.stream().collect(Collectors.toList()); Set<String> streamSet = list.stream().collect(Collectors.toSet());
  1. Map与Collection的转换
Map<String, Integer> map = new HashMap<>(); map.put("Java", 1995); map.put("Python", 1991); // 获取键的集合 Set<String> keys = map.keySet(); // 获取值的集合 Collection<Integer> values = map.values(); // 获取键值对的集合 Set<Map.Entry<String, Integer>> entries = map.entrySet(); // Collection转Map(使用Stream API) List<String> list = Arrays.asList("Java", "Python", "C++"); Map<String, Integer> lengthMap = list.stream() .collect(Collectors.toMap( s -> s, // 键映射函数 String::length // 值映射函数 )); System.out.println(lengthMap); // 输出: {Java=4, C++=3, Python=6}

7. 高级主题

7.1 泛型与集合

Java泛型允许在编译时提供类型安全性,使集合更加类型安全。

示例:

// 不使用泛型(Java 5之前) List list = new ArrayList(); list.add("Java"); list.add(1); // 可以添加任何类型的对象 String s = (String) list.get(0); // 需要强制类型转换 Integer i = (Integer) list.get(1); // 需要强制类型转换 // 使用泛型(Java 5+) List<String> stringList = new ArrayList<>(); stringList.add("Java"); // stringList.add(1); // 编译错误,只能添加String类型 String s2 = stringList.get(0); // 不需要强制类型转换

泛型通配符:

示例:

// 使用上界通配符 List<? extends Number> numbers = new ArrayList<Integer>(); // 合法 // numbers.add(1); // 不合法,不能添加元素 Number n = numbers.get(0); // 合法,可以获取元素 // 使用下界通配符 List<? super Integer> integers = new ArrayList<Number>(); // 合法 integers.add(1); // 合法,可以添加Integer // Integer i = integers.get(0); // 不合法,不能直接获取 Object o = integers.get(0); // 合法,可以获取为Object

PECS原则(Producer Extends, Consumer Super):

7.2.1 Comparable接口

Comparable接口允许类的对象进行自然排序。实现这个接口的类必须提供compareTo方法。

public class Student implements Comparable<Student> { private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } @Override public int compareTo(Student other) { // 按年龄升序排序 return this.age - other.age; } @Override public String toString() { return name + " (" + age + ")"; } } // 使用 List<Student> students = new ArrayList<>(); students.add(new Student("Alice", 22)); students.add(new Student("Bob", 20)); students.add(new Student("Charlie", 25)); Collections.sort(students); // 使用自然顺序排序 System.out.println(students); // 按年龄升序输出
7.2.2 Comparator接口

Comparator接口提供了一种外部比较策略,允许在不修改类的情况下定义多种排序方式。

public class Student { private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } @Override public String toString() { return name + " (" + age + ")"; } } // 使用Comparator List<Student> students = new ArrayList<>(); students.add(new Student("Alice", 22)); students.add(new Student("Bob", 20)); students.add(new Student("Charlie", 25)); // 按年龄排序 Collections.sort(students, new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { return s1.getAge() - s2.getAge(); } }); System.out.println(students); // 按年龄升序输出 // 使用Lambda表达式(Java 8+) Collections.sort(students, (s1, s2) -> s1.getAge() - s2.getAge()); // 使用Comparator静态方法(Java 8+) Collections.sort(students, Comparator.comparingInt(Student::getAge)); // 按姓名排序 Collections.sort(students, Comparator.comparing(Student::getName)); System.out.println(students); // 按姓名升序输出 // 组合比较器 Comparator<Student> byAgeDesc = Comparator.comparingInt(Student::getAge).reversed(); Comparator<Student> byNameThenAgeDesc = Comparator.comparing(Student::getName) .thenComparing(byAgeDesc); students.sort(byNameThenAgeDesc);
7.3 自定义集合实现

尽管Java集合框架提供了丰富的实现,但有时您可能需要创建自定义的集合类。

创建自定义集合的方式:

  1. 扩展现有集合类
public class LoggingArrayList<E> extends ArrayList<E> { private static final long serialVersionUID = 1L; @Override public boolean add(E e) { System.out.println("Adding element: " + e); return super.add(e); } @Override public E remove(int index) { E element = super.remove(index); System.out.println("Removed element at index " + index + ": " + element); return element; } }
  1. 实现集合接口
public class SimpleArrayList<E> implements List<E> { private Object[] elements; private int size; public SimpleArrayList() { elements = new Object[10]; size = 0; } @Override public boolean add(E e) { ensureCapacity(); elements[size++] = e; return true; } @SuppressWarnings("unchecked") @Override public E get(int index) { checkIndex(index); return (E) elements[index]; } @Override public int size() { return size; } // 省略其他必要的方法实现... private void ensureCapacity() { if (size == elements.length) { elements = Arrays.copyOf(elements, size * 2); } } private void checkIndex(int index) { if (index < 0 || index >= size) { throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size); } } }
  1. 使用组合而非继承
public class CountingSet<E> implements Set<E> { private final Set<E> delegate; private int addCount = 0; public CountingSet(Set<E> delegate) { this.delegate = delegate; } @Override public boolean add(E e) { addCount++; return delegate.add(e); } @Override public boolean addAll(Collection<? extends E> c) { addCount += c.size(); return delegate.addAll(c); } public int getAddCount() { return addCount; } // 委托其他方法到delegate @Override public int size() { return delegate.size(); } // 省略其他委托方法... }

8. 最佳实践与常见陷阱

8.1 选择合适的集合

选择集合时应考虑的因素:

常见集合的选择指南:

8.2 性能考虑

各种集合操作的时间复杂度:

集合类型添加删除获取包含迭代
ArrayListO(1)*O(n)O(1)O(n)O(n)
LinkedListO(1)O(1)*O(n)O(n)O(n)
HashSetO(1)O(1)N/AO(1)O(n)
LinkedHashSetO(1)O(1)N/AO(1)O(n)
TreeSetO(log n)O(log n)N/AO(log n)O(n)
HashMapO(1)O(1)O(1)O(1)O(n)
LinkedHashMapO(1)O(1)O(1)O(1)O(n)
TreeMapO(log n)O(log n)O(log n)O(log n)O(n)

*:平均情况,最坏情况可能是O(n)

性能优化技巧:

8.3 常见陷阱
  1. 并发修改异常

在迭代过程中修改集合可能会导致ConcurrentModificationException

List<String> list = new ArrayList<>(); list.add("Java"); list.add("Python"); list.add("C++"); // 错误方式:可能抛出ConcurrentModificationException for (String language : list) { if (language.equals("Python")) { list.remove(language); } } // 正确方式1:使用Iterator的remove方法 Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String language = iterator.next(); if (language.equals("Python")) { iterator.remove(); } } // 正确方式2:使用removeIf方法(Java 8+) list.removeIf(language -> language.equals("Python"));
  1. Arrays.asList()的固定大小

Arrays.asList()返回的列表是固定大小的,不能添加或删除元素:

String[] array = {"Java", "Python", "C++"}; List<String> list = Arrays.asList(array); try { list.add("Go"); // 抛出UnsupportedOperationException } catch (UnsupportedOperationException e) { System.out.println("Cannot add to fixed-size list"); } // 解决方案:转换为ArrayList List<String> modifiableList = new ArrayList<>(Arrays.asList(array)); modifiableList.add("Go"); // 正常工作
  1. Map.keySet()和values()返回的视图

Map.keySet()values()返回的集合是Map的视图,修改这些集合会影响原始Map:

Map<String, Integer> map = new HashMap<>(); map.put("Java", 1995); map.put("Python", 1991); Set<String> keys = map.keySet(); keys.remove("Java"); // 同时从map中移除Java键值对 System.out.println(map); // 输出: {Python=1991}
  1. HashSet和HashMap的hashCode()和equals()合约

当使用自定义类作为HashSet的元素或HashMap的键时,必须正确实现hashCode()equals()方法:

public class Person { private String name; private int age; // 构造函数、getter和setter省略 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age == person.age && Objects.equals(name, person.name); } @Override public int hashCode() { return Objects.hash(name, age); } }
  1. 线程安全问题

大多数集合类都不是线程安全的,在多线程环境中使用时需要同步:

// 方式1:使用Collections的同步包装器 List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>()); Map<String, Integer> synchronizedMap = Collections.synchronizedMap(new HashMap<>()); // 方式2:使用并发集合 List<String> concurrentList = new CopyOnWriteArrayList<>(); Map<String, Integer> concurrentMap = new ConcurrentHashMap<>();
  1. 比较器的一致性

当使用自定义比较器时,确保符合一致性要求:

// 不一致的比较器(违反了传递性) Comparator<Integer> inconsistentComparator = new Comparator<Integer>() { @Override public int compare(Integer a, Integer b) { return (a % 2) - (b % 2); // 只比较奇偶性 } };

9. 总结与进阶学习

9.1 总结

Java集合框架提供了一组丰富的接口和实现类,用于存储和操作数据:

选择合适的集合类型取决于多种因素,包括访问模式、排序要求、性能需求等。

9.2 进阶学习路径

要深入学习Java集合框架,可以考虑以下进阶主题:

  1. Java 8+ Stream API:更加函数式的集合操作方式
  2. 并发集合和原子操作:java.util.concurrent包中的类
  3. 第三方集合库:如Apache Commons Collections, Google Guava
  4. 集合性能优化:如何优化集合操作的性能
  5. 数据结构原理:学习集合类背后的数据结构
9.3 学习资源

书籍:

在线资源:

说真的,这两年看着身边一个个搞Java、C++、前端、数据、架构的开始卷大模型,挺唏嘘的。大家最开始都是写接口、搞Spring Boot、连数据库、配Redis,稳稳当当过日子。

结果GPT、DeepSeek火了之后,整条线上的人都开始有点慌了,大家都在想:“我是不是要学大模型,不然这饭碗还能保多久?”

先给出最直接的答案:一定要把现有的技术和大模型结合起来,而不是抛弃你们现有技术!掌握AI能力的Java工程师比纯Java岗要吃香的多。

即使现在裁员、降薪、团队解散的比比皆是……但后续的趋势一定是AI应用落地!大模型方向才是实现职业升级、提升薪资待遇的绝佳机遇!

如何学习AGI大模型?

作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

2025最新版CSDN大礼包:《AGI大模型学习资源包》免费分享**

一、2025最新大模型学习路线

一个明确的学习路线可以帮助新人了解从哪里开始,按照什么顺序学习,以及需要掌握哪些知识点。大模型领域涉及的知识点非常广泛,没有明确的学习路线可能会导致新人感到迷茫,不知道应该专注于哪些内容。

我们把学习路线分成L1到L4四个阶段,一步步带你从入门到进阶,从理论到实战。

L1级别:AI大模型时代的华丽登场

L1阶段:我们会去了解大模型的基础知识,以及大模型在各个行业的应用和分析;学习理解大模型的核心原理,关键技术,以及大模型应用场景;通过理论原理结合多个项目实战,从提示工程基础到提示工程进阶,掌握Prompt提示工程。

L2级别:AI大模型RAG应用开发工程

L2阶段是我们的AI大模型RAG应用开发工程,我们会去学习RAG检索增强生成:包括Naive RAG、Advanced-RAG以及RAG性能评估,还有GraphRAG在内的多个RAG热门项目的分析。

L3级别:大模型Agent应用架构进阶实践

L3阶段:大模型Agent应用架构进阶实现,我们会去学习LangChain、 LIamaIndex框架,也会学习到AutoGPT、 MetaGPT等多Agent系统,打造我们自己的Agent智能体;同时还可以学习到包括Coze、Dify在内的可视化工具的使用。

L4级别:大模型微调与私有化部署

L4阶段:大模型的微调和私有化部署,我们会更加深入的探讨Transformer架构,学习大模型的微调技术,利用DeepSpeed、Lamam Factory等工具快速进行模型微调;并通过Ollama、vLLM等推理部署框架,实现模型的快速部署。

整个大模型学习路线L1主要是对大模型的理论基础、生态以及提示词他的一个学习掌握;而L3 L4更多的是通过项目实战来掌握大模型的应用开发,针对以上大模型的学习路线我们也整理了对应的学习视频教程,和配套的学习资料。

二、大模型经典PDF书籍

书籍和学习文档资料是学习大模型过程中必不可少的,我们精选了一系列深入探讨大模型技术的书籍和学习文档,它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础(书籍含电子版PDF)

三、大模型视频教程

对于很多自学或者没有基础的同学来说,书籍这些纯文字类的学习教材会觉得比较晦涩难以理解,因此,我们提供了丰富的大模型视频教程,以动态、形象的方式展示技术概念,帮助你更快、更轻松地掌握核心知识

四、大模型项目实战

学以致用,当你的理论知识积累到一定程度,就需要通过项目实战,在实际操作中检验和巩固你所学到的知识,同时为你找工作和职业发展打下坚实的基础。

五、大模型面试题

面试不仅是技术的较量,更需要充分的准备。

在你已经掌握了大模型技术之后,就需要开始准备面试,我们将提供精心整理的大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。


因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

2025最新版CSDN大礼包:《AGI大模型学习资源包》免费分享

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!