1. Java集合框架概述Java集合框架是Java语言中最重要的基础库之一它位于java.util包中提供了一套性能优良、使用方便的数据结构和算法。作为一名Java开发者我几乎每天都会与各种集合类打交道它们就像是程序员的工具箱不同的集合类适用于不同的场景。集合框架主要包含两种类型的容器Collection接口及其子接口存储单一元素的集合Map接口及其实现类存储键值对的映射关系在实际开发中我们最常用的集合类包括ArrayList、LinkedList、HashSet、HashMap等。每种集合类都有其特定的使用场景和性能特点选择不当可能会导致程序性能下降甚至出现线程安全问题。2. Collection接口及其实现类2.1 List接口及常用实现List接口代表有序、可重复的集合它允许精确控制每个元素的插入位置并通过索引访问元素。我经常使用的List实现类有ArrayList基于动态数组实现是我最常用的List实现。它的随机访问性能非常好O(1)时间复杂度但在中间插入或删除元素时性能较差需要移动后续元素。适合读多写少的场景。// ArrayList基本用法 ListString arrayList new ArrayList(); arrayList.add(Java); arrayList.add(Python); arrayList.add(1, C); // 在指定位置插入 String element arrayList.get(0); // 随机访问LinkedList基于双向链表实现插入和删除操作性能优异O(1)时间复杂度但随机访问性能较差需要遍历链表。适合频繁插入删除的场景。// LinkedList基本用法 ListString linkedList new LinkedList(); linkedList.add(Apple); linkedList.addFirst(Banana); // 在头部插入 linkedList.addLast(Orange); // 在尾部插入 String first linkedList.getFirst(); // 获取第一个元素Vector与ArrayList类似但是线程安全的。由于同步带来的性能开销在现代Java开发中已经很少使用通常会用Collections.synchronizedList()来包装ArrayList或者直接使用CopyOnWriteArrayList。2.2 Set接口及常用实现Set接口代表无序、不可重复的集合它继承自Collection接口但不添加任何新方法。常用的Set实现类有HashSet基于HashMap实现使用哈希表存储元素具有最好的查找性能O(1)平均时间复杂度。不保证元素的顺序。// HashSet基本用法 SetString hashSet new HashSet(); hashSet.add(Java); hashSet.add(Python); hashSet.add(Java); // 重复元素不会被添加 boolean contains hashSet.contains(Java); // 快速查找LinkedHashSet继承自HashSet但维护了一个双向链表来记录插入顺序因此可以按照插入顺序遍历元素。TreeSet基于红黑树实现可以按照元素的自然顺序或者自定义比较器进行排序。查找、插入和删除操作的时间复杂度都是O(log n)。// TreeSet基本用法 SetString treeSet new TreeSet(); treeSet.add(Java); treeSet.add(Python); treeSet.add(C); // 元素会按照字母顺序排序 for(String lang : treeSet) { System.out.println(lang); }3. Map接口及其实现类Map接口存储键值对映射常用的实现类有3.1 HashMap基于哈希表实现允许null键和null值不保证顺序。查找、插入和删除操作的平均时间复杂度都是O(1)。// HashMap基本用法 MapString, Integer hashMap new HashMap(); hashMap.put(Java, 1); hashMap.put(Python, 2); hashMap.put(null, 3); // 允许null键 Integer value hashMap.get(Java); // 通过键获取值 boolean containsKey hashMap.containsKey(Python);3.2 LinkedHashMap继承自HashMap但维护了一个双向链表来记录插入顺序或访问顺序。可以用来实现LRU缓存。// LinkedHashMap基本用法 MapString, Integer linkedHashMap new LinkedHashMap(); linkedHashMap.put(Java, 1); linkedHashMap.put(Python, 2); linkedHashMap.put(C, 3); // 遍历时会按照插入顺序输出3.3 TreeMap基于红黑树实现可以按照键的自然顺序或自定义比较器进行排序。查找、插入和删除操作的时间复杂度都是O(log n)。// TreeMap基本用法 MapString, Integer treeMap new TreeMap(); treeMap.put(Java, 1); treeMap.put(Python, 2); treeMap.put(C, 3); // 遍历时会按照键的字母顺序输出4. 集合的遍历与迭代器4.1 遍历ListList有三种常见的遍历方式ListString list Arrays.asList(Java, Python, C); // 1. for循环 for(int i 0; i list.size(); i) { System.out.println(list.get(i)); } // 2. 增强for循环 for(String lang : list) { System.out.println(lang); } // 3. 使用迭代器 IteratorString iterator list.iterator(); while(iterator.hasNext()) { System.out.println(iterator.next()); }4.2 遍历MapMap有四种常见的遍历方式MapString, Integer map new HashMap(); map.put(Java, 1); map.put(Python, 2); map.put(C, 3); // 1. 遍历键 for(String key : map.keySet()) { System.out.println(key : map.get(key)); } // 2. 遍历键值对(entrySet) for(Map.EntryString, Integer entry : map.entrySet()) { System.out.println(entry.getKey() : entry.getValue()); } // 3. 遍历值 for(Integer value : map.values()) { System.out.println(value); } // 4. 使用迭代器 IteratorMap.EntryString, Integer iterator map.entrySet().iterator(); while(iterator.hasNext()) { Map.EntryString, Integer entry iterator.next(); System.out.println(entry.getKey() : entry.getValue()); }4.3 迭代器的使用注意事项在实际开发中我经常遇到需要在遍历集合时修改集合的情况。这时直接使用集合的remove()方法会抛出ConcurrentModificationException异常。正确的做法是使用迭代器的remove()方法ListString list new ArrayList(Arrays.asList(Java, Python, C)); // 错误的做法 - 会抛出ConcurrentModificationException for(String lang : list) { if(lang.equals(Python)) { list.remove(lang); // 直接调用集合的remove方法 } } // 正确的做法 IteratorString iterator list.iterator(); while(iterator.hasNext()) { String lang iterator.next(); if(lang.equals(Python)) { iterator.remove(); // 使用迭代器的remove方法 } }5. 集合工具类CollectionsJava提供了Collections工具类包含许多操作集合的静态方法。以下是我常用的几个方法5.1 排序ListInteger numbers Arrays.asList(3, 1, 4, 1, 5, 9); // 自然排序 Collections.sort(numbers); System.out.println(numbers); // [1, 1, 3, 4, 5, 9] // 自定义排序 Collections.sort(numbers, Collections.reverseOrder()); System.out.println(numbers); // [9, 5, 4, 3, 1, 1]5.2 查找和替换ListString list Arrays.asList(Java, Python, C, Java); // 查找元素出现次数 int frequency Collections.frequency(list, Java); // 2 // 查找最大最小值 String max Collections.max(list); // Python (按字母顺序) String min Collections.min(list); // C // 替换所有匹配元素 Collections.replaceAll(list, Java, JavaScript);5.3 同步包装// 创建线程安全的List ListString syncList Collections.synchronizedList(new ArrayList()); // 创建线程安全的Set SetString syncSet Collections.synchronizedSet(new HashSet()); // 创建线程安全的Map MapString, Integer syncMap Collections.synchronizedMap(new HashMap());6. 集合的性能比较与选择在实际项目中选择合适的集合类对性能有很大影响。以下是我总结的一些经验6.1 List实现比较特性ArrayListLinkedListVector底层实现动态数组双向链表动态数组随机访问性能O(1) - 优秀O(n) - 差O(1) - 优秀插入/删除(头部)O(n) - 差O(1) - 优秀O(n) - 差插入/删除(尾部)O(1) - 优秀O(1) - 优秀O(1) - 优秀插入/删除(中间)O(n) - 差O(n) - 中等O(n) - 差内存占用较小较大较小线程安全不安全不安全安全选择建议需要频繁随机访问ArrayList需要频繁在头部或中间插入删除LinkedList需要线程安全CopyOnWriteArrayList或Collections.synchronizedList()6.2 Set实现比较特性HashSetLinkedHashSetTreeSet底层实现HashMapLinkedHashMap红黑树元素顺序无序插入顺序排序顺序基本操作时间复杂度O(1)O(1)O(log n)允许null元素是是否(除非比较器允许)线程安全不安全不安全不安全选择建议需要最快查找速度且不关心顺序HashSet需要保持插入顺序LinkedHashSet需要元素排序TreeSet6.3 Map实现比较特性HashMapLinkedHashMapTreeMapHashtable底层实现哈希表哈希表链表红黑树哈希表键值顺序无序插入/访问顺序键排序无序基本操作时间复杂度O(1)O(1)O(log n)O(1)允许null键/值是/是是/是否/是(取决于比较器)否/否线程安全不安全不安全不安全安全选择建议一般用途HashMap需要保持插入或访问顺序LinkedHashMap需要键排序TreeMap需要线程安全ConcurrentHashMap(优于Hashtable)7. Java 8对集合的增强Java 8为集合框架引入了许多新特性大大提高了开发效率7.1 forEach方法ListString languages Arrays.asList(Java, Python, C); // 传统方式 for(String lang : languages) { System.out.println(lang); } // Java 8方式 languages.forEach(System.out::println);7.2 removeIf方法ListString list new ArrayList(Arrays.asList(Java, Python, C)); // 传统方式 IteratorString iterator list.iterator(); while(iterator.hasNext()) { if(iterator.next().startsWith(P)) { iterator.remove(); } } // Java 8方式 list.removeIf(s - s.startsWith(P));7.3 Stream APIListString languages Arrays.asList(Java, Python, C, JavaScript, Ruby); // 过滤并收集 ListString filtered languages.stream() .filter(l - l.startsWith(J)) .collect(Collectors.toList()); // 映射 ListInteger lengths languages.stream() .map(String::length) .collect(Collectors.toList()); // 排序 ListString sorted languages.stream() .sorted() .collect(Collectors.toList()); // 统计 long count languages.stream() .filter(l - l.length() 3) .count();7.4 Map的增强方法MapString, Integer map new HashMap(); map.put(Java, 1); map.put(Python, 2); map.put(C, 3); // getOrDefault int value map.getOrDefault(Ruby, 0); // 返回0而不是null // putIfAbsent map.putIfAbsent(Java, 4); // 不会替换现有值 map.putIfAbsent(Ruby, 4); // 会添加新条目 // compute map.compute(Java, (k, v) - v 10); // Java的值变为11 // merge map.merge(Java, 1, (oldValue, newValue) - oldValue newValue); // Java的值变为128. 集合使用的最佳实践根据我多年的开发经验总结了一些集合使用的最佳实践8.1 初始化集合时指定容量对于ArrayList、HashMap等基于数组实现的集合如果能够预估元素数量最好在创建时指定初始容量避免频繁扩容带来的性能开销。// 不好的做法 - 默认初始容量小可能需多次扩容 ListString list1 new ArrayList(); MapString, Integer map1 new HashMap(); // 好的做法 - 指定初始容量 ListString list2 new ArrayList(100); MapString, Integer map2 new HashMap(100);8.2 使用不可变集合当需要返回或共享不会修改的集合时使用不可变集合可以避免意外修改提高安全性。// 创建不可变List ListString immutableList Collections.unmodifiableList(new ArrayList()); // 创建不可变Set SetString immutableSet Collections.unmodifiableSet(new HashSet()); // Java 9 提供了更简洁的工厂方法 ListString list List.of(Java, Python, C); SetString set Set.of(Java, Python, C); MapString, Integer map Map.of(Java, 1, Python, 2);8.3 注意集合的线程安全性大多数集合实现不是线程安全的在多线程环境下使用时需要特别注意// 不安全的做法 ListString unsafeList new ArrayList(); // 安全的做法1 - 使用同步包装 ListString safeList1 Collections.synchronizedList(new ArrayList()); // 安全的做法2 - 使用并发集合 ListString safeList2 new CopyOnWriteArrayList(); MapString, Integer safeMap new ConcurrentHashMap();8.4 正确实现equals和hashCode当自定义对象作为HashMap的键或HashSet的元素时必须正确实现equals和hashCode方法否则会导致无法正确查找元素。class Person { private String name; private int age; // 构造方法等省略... 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); } }8.5 选择合适的集合实现根据具体需求选择合适的集合实现考虑以下因素是否需要保持元素顺序是否需要元素排序主要操作是插入、删除还是查找是否需要线程安全集合预期的大小例如需要频繁随机访问ArrayList需要频繁插入删除LinkedList需要去重且不关心顺序HashSet需要去重且保持插入顺序LinkedHashSet需要键值对存储HashMap需要线程安全的MapConcurrentHashMap9. 常见问题与解决方案在实际开发中我遇到过许多与集合相关的问题以下是几个典型问题及其解决方案9.1 ConcurrentModificationException这是遍历集合时修改集合导致的常见异常。解决方案使用迭代器的remove()方法而不是集合的remove()方法使用并发集合如CopyOnWriteArrayList先收集要删除的元素遍历完后再统一删除ListString list new ArrayList(Arrays.asList(Java, Python, C)); // 解决方案1 - 使用迭代器 IteratorString iterator list.iterator(); while(iterator.hasNext()) { String lang iterator.next(); if(lang.equals(Python)) { iterator.remove(); } } // 解决方案2 - 使用并发集合 ListString copyOnWriteList new CopyOnWriteArrayList(list); for(String lang : copyOnWriteList) { if(lang.equals(Python)) { copyOnWriteList.remove(lang); } } // 解决方案3 - 先收集再删除 ListString toRemove new ArrayList(); for(String lang : list) { if(lang.equals(Python)) { toRemove.add(lang); } } list.removeAll(toRemove);9.2 集合性能问题当集合操作变慢时可以考虑对于ArrayList如果频繁在中间插入删除考虑改用LinkedList对于HashMap如果哈希冲突严重可以调整初始容量和负载因子对于大型集合考虑使用更高效的数据结构如Trove库// 优化HashMap性能 MapString, Integer optimizedMap new HashMap(1000, 0.75f);9.3 内存泄漏问题当集合持有对象的引用导致无法被垃圾回收时会发生内存泄漏。常见场景使用静态集合缓存数据但从不清理将集合作为缓存但无过期策略对象作为Map的键但修改了影响hashCode的字段解决方案使用WeakHashMap当键不再被其他对象引用时自动移除条目实现定期清理机制确保作为键的对象是不可变的// 使用WeakHashMap避免内存泄漏 MapObject, String weakMap new WeakHashMap(); Object key new Object(); weakMap.put(key, value); key null; // 当key不再被强引用时WeakHashMap中的条目会被自动移除9.4 集合排序问题当需要对自定义对象集合排序时实现Comparable接口定义自然排序使用Comparator提供多种排序方式注意compareTo与equals的一致性class Person implements ComparablePerson { private String name; private int age; // 构造方法等省略... Override public int compareTo(Person other) { return this.name.compareTo(other.name); } } // 使用 ListPerson people new ArrayList(); // 添加人员... Collections.sort(people); // 使用Comparator定义其他排序方式 ComparatorPerson byAge Comparator.comparingInt(Person::getAge); people.sort(byAge);10. Java集合的高级用法10.1 使用EnumSet和EnumMap当处理枚举类型时EnumSet和EnumMap是更高效的选择enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY } // EnumSet EnumSetDay weekend EnumSet.of(Day.SATURDAY, Day.SUNDAY); EnumSetDay allDays EnumSet.allOf(Day.class); // EnumMap EnumMapDay, String activityMap new EnumMap(Day.class); activityMap.put(Day.MONDAY, Work); activityMap.put(Day.FRIDAY, Party);10.2 使用Collections类的特殊方法Collections类提供了许多有用的静态方法// 创建空集合(不可变) ListString emptyList Collections.emptyList(); SetInteger emptySet Collections.emptySet(); MapString, String emptyMap Collections.emptyMap(); // 创建单元素集合(不可变) ListString singletonList Collections.singletonList(Java); SetInteger singletonSet Collections.singleton(1); MapString, String singletonMap Collections.singletonMap(key, value); // 反转列表 ListInteger numbers new ArrayList(Arrays.asList(1, 2, 3)); Collections.reverse(numbers); // [3, 2, 1] // 随机打乱 Collections.shuffle(numbers);10.3 使用Arrays工具类Arrays类提供了数组与集合之间的转换方法// 数组转List(返回的List是固定大小的) String[] array {Java, Python, C}; ListString list Arrays.asList(array); // List转数组 String[] newArray list.toArray(new String[0]); // 数组排序 Arrays.sort(array); // 数组二分查找 int index Arrays.binarySearch(array, Python);10.4 使用Guava集合工具Google的Guava库提供了许多增强的集合工具// 创建不可变集合 ImmutableListString immutableList ImmutableList.of(Java, Python, C); ImmutableSetInteger immutableSet ImmutableSet.of(1, 2, 3); ImmutableMapString, Integer immutableMap ImmutableMap.of(Java, 1, Python, 2); // 多值Map MultimapString, String multimap ArrayListMultimap.create(); multimap.put(Languages, Java); multimap.put(Languages, Python); CollectionString languages multimap.get(Languages); // 双向Map BiMapString, Integer biMap HashBiMap.create(); biMap.put(Java, 1); biMap.put(Python, 2); Integer javaValue biMap.get(Java); // 1 String keyFor1 biMap.inverse().get(1); // Java11. Java集合的线程安全替代方案在多线程环境下除了使用Collections.synchronizedXXX()方法包装集合外Java还提供了专门的并发集合类11.1 CopyOnWriteArrayList适合读多写少的场景写操作时复制整个底层数组ListString concurrentList new CopyOnWriteArrayList(); concurrentList.add(Java); concurrentList.add(Python); // 遍历时安全但可能看到旧数据 for(String lang : concurrentList) { System.out.println(lang); }11.2 ConcurrentHashMap高并发的HashMap实现采用分段锁技术MapString, Integer concurrentMap new ConcurrentHashMap(); concurrentMap.put(Java, 1); concurrentMap.put(Python, 2); // 原子操作 concurrentMap.computeIfAbsent(C, k - 3);11.3 ConcurrentSkipListSet和ConcurrentSkipListMap基于跳表实现的并发有序集合SetString concurrentSet new ConcurrentSkipListSet(); concurrentSet.add(Java); concurrentSet.add(Python); MapString, Integer concurrentSortedMap new ConcurrentSkipListMap(); concurrentSortedMap.put(Java, 1); concurrentSortedMap.put(Python, 2);11.4 BlockingQueue实现用于生产者-消费者模式的阻塞队列// 有界队列 BlockingQueueString boundedQueue new ArrayBlockingQueue(100); // 无界队列 BlockingQueueString unboundedQueue new LinkedBlockingQueue(); // 优先级阻塞队列 BlockingQueueString priorityQueue new PriorityBlockingQueue(); // 特殊操作的队列 BlockingQueueString delayQueue new DelayQueue();12. Java集合的内存优化技巧在处理大量数据时集合的内存使用变得尤为重要12.1 使用基本类型集合避免自动装箱拆箱的开销可以使用第三方库如Trove// 传统方式 - 有装箱开销 ListInteger list new ArrayList(); list.add(1); // 自动装箱 // 使用Trove TIntArrayList troveList new TIntArrayList(); troveList.add(1); // 直接存储基本类型12.2 合理设置集合初始大小避免频繁扩容根据数据量合理设置初始容量// 预计有1000个元素负载因子0.75 MapString, Integer map new HashMap(1334); // 1000 / 0.7512.3 使用Flyweight模式共享对象对于不可变对象可以共享实例减少内存使用// 不好的做法 - 创建大量相同值的对象 ListInteger list1 new ArrayList(); for(int i 0; i 1000; i) { list1.add(10); // 创建1000个Integer对象 } // 好的做法 - 共享同一个对象 Integer sharedValue 10; ListInteger list2 new ArrayList(); for(int i 0; i 1000; i) { list2.add(sharedValue); // 共享同一个Integer对象 }12.4 及时清理不再使用的集合大型集合不再使用时及时置为null帮助GC回收ListBigData bigDataList loadHugeData(); processData(bigDataList); bigDataList null; // 帮助GC回收内存13. Java集合的序列化与反序列化集合类大多实现了Serializable接口可以方便地进行序列化13.1 基本序列化ListString list new ArrayList(Arrays.asList(Java, Python, C)); // 序列化 try (ObjectOutputStream oos new ObjectOutputStream(new FileOutputStream(list.ser))) { oos.writeObject(list); } // 反序列化 try (ObjectInputStream ois new ObjectInputStream(new FileInputStream(list.ser))) { SuppressWarnings(unchecked) ListString deserializedList (ListString) ois.readObject(); System.out.println(deserializedList); }13.2 自定义序列化对于包含不可序列化元素的集合或者需要自定义序列化过程的集合可以实现Externalizable接口class CustomListE extends ArrayListE implements Externalizable { // 必须有无参构造方法 public CustomList() { super(); } Override public void writeExternal(ObjectOutput out) throws IOException { out.writeInt(size()); for(E element : this) { out.writeObject(element); } } Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { int size in.readInt(); for(int i 0; i size; i) { SuppressWarnings(unchecked) E element (E) in.readObject(); add(element); } } }13.3 序列化注意事项确保集合中的所有元素都是可序列化的注意transient字段不会被序列化考虑序列化版本UIDserialVersionUID以保证兼容性大型集合序列化时考虑分块或压缩14. Java集合与函数式编程Java 8引入的函数式特性与集合结合可以写出更简洁的代码14.1 使用Stream处理集合ListString languages Arrays.asList(Java, Python, C, JavaScript, null, Ruby); // 过滤null和空字符串 ListString filtered languages.stream() .filter(Objects::nonNull) .filter(s - !s.isEmpty()) .collect(Collectors.toList()); // 转换大小写 ListString upperCase languages.stream() .filter(Objects::nonNull) .map(String::toUpperCase) .collect(Collectors.toList()); // 分组 MapInteger, ListString byLength languages.stream() .filter(Objects::nonNull) .collect(Collectors.groupingBy(String::length)); // 统计 IntSummaryStatistics stats languages.stream() .filter(Objects::nonNull) .mapToInt(String::length) .summaryStatistics();14.2 使用方法引用ListString list Arrays.asList(Java, Python, C); // 使用方法引用 list.forEach(System.out::println); // 排序 list.sort(String::compareToIgnoreCase);14.3 使用Optional处理可能为null的集合元素ListString listWithNulls Arrays.asList(Java, null, Python, null, C); // 安全处理null元素 listWithNulls.stream() .map(Optional::ofNullable) .filter(Optional::isPresent) .map(Optional::get) .forEach(System.out::println);15. 集合性能测试与调优15.1 基准测试示例使用JMH进行集合性能测试BenchmarkMode(Mode.AverageTime) OutputTimeUnit(TimeUnit.NANOSECONDS) State(Scope.Benchmark) public class ListBenchmark { private ListInteger arrayList; private ListInteger linkedList; Setup public void setup() { arrayList new ArrayList(Arrays.asList(1, 2, 3, 4, 5)); linkedList new LinkedList(Arrays.asList(1, 2, 3, 4, 5)); } Benchmark public Integer arrayListGet() { return arrayList.get(2); } Benchmark public Integer linkedListGet() { return linkedList.get(2); } }15.2 常见性能优化技巧ArrayList优化预分配足够大的初始容量避免频繁在中间位置插入/删除考虑使用trimToSize()释放多余空间LinkedList优化使用ListIterator进行中间位置插入避免随机访问操作(get(index))HashMap优化设置合理的初始容量和负载因子使用完美哈希函数减少冲突对于不可变键缓存hashCode值HashSet优化确保元素类型正确实现了hashCode和equals对于大型集合考虑增加初始容量15.3 内存占用分析使用JOL(Java Object Layout)分析集合内存占用public class MemoryLayout { public static void main(String[] args) { System.out.println(ClassLayout.parseClass(ArrayList.class).toPrintable()); System.out.println(ClassLayout.parseInstance(new ArrayList()).toPrintable()); System.out.println(ClassLayout.parseInstance(new HashMap()).toPrintable()); } }16. Java集合的未来发展随着Java版本的更新集合框架也在不断演进16.1 Java 9的集合工厂方法Java 9引入了更简洁的创建不可变集合的方法// 不可变List ListString immutableList List.of(Java, Python, C); // 不可变Set SetString immutableSet Set.of(Java, Python, C); // 不可变Map MapString, Integer immutableMap Map.of(Java, 1, Python, 2, C, 3); // 更多元素的Map MapString, Integer biggerMap Map.ofEntries( Map.entry(Java, 1), Map.entry(Python, 2), Map.entry(C, 3), Map.entry(JavaScript, 4) );16.2 Java 10的不可变集合拷贝方法Java 10添加了创建不可变集合拷贝的方法ListString original new ArrayList(Arrays.asList(Java, Python, C)); // 创建不可变拷贝 ListString copy List.copyOf(original); SetString setCopy Set.copyOf(original); MapString, Integer mapCopy Map.copyOf(original.stream() .collect(Collectors.toMap(Function.identity(), String::length)));16.3 Java 16的Stream.toList()方法Java 16简化了Stream转换为List的操作// Java 16之前 ListString list1 stream.collect(Collectors.toList()); // Java 16 ListString list2 stream.toList(); // 返回不可变List16.4 未来可能的变化根据Java社区的趋势未来可能会有更多不可变集合的支持值类型(Valhalla项目)对集合的影响更好的原生类型集合支持更强大的模式匹配与集合操作的集成17. 第三方集合库介绍除了Java标准库还有许多优秀的第三方集合库17.1 Google Guava提供不可变集合、多值Map、表格等高级数据结构// 不可变集合 ImmutableListString immutableList ImmutableList.of(Java, Python, C); // 多值Map MultimapString, String multimap ArrayListMultimap.create(); multimap.put(Languages, Java); multimap.put(Languages, Python); // 表格结构 TableString, String, Integer table HashBasedTable.create(); table.put(Row1, Column1, 1); table.put(Row1, Column2, 2);17.2 Eclipse Collections高性能集合框架提供原始类型特化集合// 原始类型列表 IntList intList IntLists.mutable.with(1, 2, 3); LongList longList LongLists.mutable.with(1L, 2L, 3L); // 双向Map BiMapString, Integer biMap HashBiMap.newWithKeysValues(One, 1, Two, 2);17.3 Apache Commons Collections提供许多特殊用途的集合实现// 双向Map BidiMapString, Integer bidiMap new DualHashBidiMap(); bidiMap.put(One, 1); bidiMap.put(Two, 2); // 多值Map MultiValuedMapString, String multiMap new ArrayListValuedHashMap(); multiMap.put(Language, Java); multiMap.put(Language, Python);17.4 Trove原始类型集合实现避免装箱拆箱开销// 原始类型集合 TIntList intList new TIntArrayList(); intList.add(1); intList.add(2