当前位置: 首页 > news >正文

Java集合框架解析

一、集合框架概述

1. 集合框架体系结构

Java集合框架(Java Collections Framework, JCF)位于java.util包中,包含三大核心接口:

  • Collection:单列数据集合的根接口
    • List:有序可重复集合
    • Set:无序不可重复集合
    • Queue:队列集合
  • Map:双列键值对集合
  • Iterator:集合遍历接口

2. 核心接口继承关系

Collection
├── List
│   ├── ArrayList
│   ├── LinkedList
│   └── Vector
│       └── Stack
├── Set
│   ├── HashSet
│   │   └── LinkedHashSet
│   └── SortedSet
│       └── TreeSet
└── Queue├── Deque│   ├── ArrayDeque│   └── LinkedList└── PriorityQueueMap
├── HashMap
│   └── LinkedHashMap
├── Hashtable
└── SortedMap└── TreeMap

二、基础集合使用

1. List接口实现

ArrayList
// 创建ArrayList
List<String> arrayList = new ArrayList<>();// 添加元素
arrayList.add("Java");
arrayList.add("Python");
arrayList.add(1, "C++"); // 在指定位置插入// 访问元素
String lang = arrayList.get(0); // "Java"// 遍历
for (String s : arrayList) {System.out.println(s);
}// 删除元素
arrayList.remove("Python");
arrayList.remove(0);
LinkedList
// 创建LinkedList
List<String> linkedList = new LinkedList<>();// 特有方法
LinkedList<String> list = (LinkedList<String>) linkedList;
list.addFirst("First");
list.addLast("Last");
String first = list.getFirst();
String last = list.getLast();

2. Set接口实现

HashSet
Set<String> hashSet = new HashSet<>();
hashSet.add("Apple");
hashSet.add("Banana");
hashSet.add("Apple"); // 重复元素不会被添加System.out.println(hashSet); // [Apple, Banana]
TreeSet
Set<Integer> treeSet = new TreeSet<>((a, b) -> b - a); // 自定义排序
treeSet.add(5);
treeSet.add(2);
treeSet.add(8);System.out.println(treeSet); // [8, 5, 2]

3. Map接口实现

HashMap
Map<String, Integer> hashMap = new HashMap<>();
hashMap.put("Alice", 25);
hashMap.put("Bob", 30);
hashMap.put("Charlie", 28);// 获取值
int age = hashMap.get("Bob");// 遍历
for (Map.Entry<String, Integer> entry : hashMap.entrySet()) {System.out.println(entry.getKey() + ": " + entry.getValue());
}
TreeMap
Map<String, Integer> treeMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
treeMap.put("Banana", 3);
treeMap.put("apple", 5);
treeMap.put("Orange", 2);System.out.println(treeMap); // {apple=5, Banana=3, Orange=2}

三、集合转换操作

1. 集合间相互转换

List ↔ Set
// List转Set(去重)
List<String> listWithDuplicates = Arrays.asList("A", "B", "A", "C");
Set<String> set = new HashSet<>(listWithDuplicates); // [A, B, C]// Set转List
List<String> listFromSet = new ArrayList<>(set);
数组 ↔ List
// 数组转List
String[] array = {"Java", "Python", "C++"};
List<String> list = Arrays.asList(array); // 固定大小List
List<String> mutableList = new ArrayList<>(Arrays.asList(array));// List转数组
String[] newArray = list.toArray(new String[0]);
Map ↔ Set
// Map的key转Set
Set<String> keys = hashMap.keySet();// Map的entry转Set
Set<Map.Entry<String, Integer>> entries = hashMap.entrySet();// Set转Map(需要元素包含键值信息)
Set<Pair<String, Integer>> pairSet = new HashSet<>();
// ...添加元素
Map<String, Integer> mapFromSet = pairSet.stream().collect(Collectors.toMap(Pair::getKey, Pair::getValue));

2. 不可变集合

Java 9+创建不可变集合
List<String> immutableList = List.of("A", "B", "C");
Set<Integer> immutableSet = Set.of(1, 2, 3);
Map<String, Integer> immutableMap = Map.of("A", 1, "B", 2);// 尝试修改会抛出UnsupportedOperationException
// immutableList.add("D"); // 错误
Collections工具类创建
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
List<String> unmodifiableList = Collections.unmodifiableList(list);

四、集合流式处理(Java 8+)

1. 基本流操作

过滤与映射
List<String> languages = Arrays.asList("Java", "Python", "C++", "JavaScript", "Ruby");// 过滤长度大于3的元素
List<String> filtered = languages.stream().filter(s -> s.length() > 3).collect(Collectors.toList()); // [Java, Python, JavaScript, Ruby]// 转换为大写
List<String> upperCase = languages.stream().map(String::toUpperCase).collect(Collectors.toList());
聚合操作
// 统计
long count = languages.stream().count();
Optional<String> max = languages.stream().max(Comparator.naturalOrder());// 求和
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream().reduce(0, Integer::sum);

2. 高级流操作

分组与分区
// 按长度分组
Map<Integer, List<String>> groupByLength = languages.stream().collect(Collectors.groupingBy(String::length));
// {2=[C++], 4=[Java, Ruby], 6=[Python], 10=[JavaScript]}// 分区(满足条件的和其他的)
Map<Boolean, List<String>> partition = languages.stream().collect(Collectors.partitioningBy(s -> s.startsWith("J")));
// {false=[Python, C++, Ruby], true=[Java, JavaScript]}
并行流
// 顺序流
long count = languages.stream().filter(s -> s.length() > 3).count();// 并行流(大数据量性能更好)
long parallelCount = languages.parallelStream().filter(s -> s.length() > 3).count();

五、集合与数组转换

1. 集合转数组

传统方式
List<String> list = Arrays.asList("A", "B", "C");
String[] array = list.toArray(new String[0]); // 推荐使用空数组
Java 8+ Stream方式
String[] array = list.stream().toArray(String[]::new);

2. 数组转集合

标准方式
String[] array = {"A", "B", "C"};// 固定大小List(不可修改)
List<String> asList = Arrays.asList(array);// 可变List
List<String> mutableList = new ArrayList<>(Arrays.asList(array));
Java 8+ Stream方式
List<String> list = Arrays.stream(array).collect(Collectors.toList());// 去重
Set<String> set = Arrays.stream(array).collect(Collectors.toSet());

六、集合框架底层实现

1. ArrayList实现原理

  • 底层结构:动态数组Object[] elementData
  • 扩容机制
    • 默认初始容量10
    • 扩容时newCapacity = oldCapacity + (oldCapacity >> 1)(约1.5倍)
    • 最大容量Integer.MAX_VALUE - 8
  • 特点
    • 随机访问快(O(1))
    • 插入删除慢(平均O(n))
    • 线程不安全

2. LinkedList实现原理

  • 底层结构:双向链表
    private static class Node<E> {E item;Node<E> next;Node<E> prev;// ...
    }
    
  • 特点
    • 插入删除快(O(1))
    • 随机访问慢(O(n))
    • 实现了List和Deque接口

3. HashMap实现原理(Java 8+)

  • 底层结构:数组+链表+红黑树
    • 默认初始容量16,负载因子0.75
    • 链表长度>8且数组长度≥64时,链表转红黑树
    • 树节点数<6时,红黑树转链表
  • 哈希计算
    static final int hash(Object key) {int h;return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
    
  • 扩容机制
    • 容量变为2倍
    • 重新计算节点位置:newTab[e.hash & (newCap - 1)]

4. TreeMap实现原理

  • 底层结构:红黑树(自平衡二叉查找树)
  • 排序规则
    • 自然排序(元素实现Comparable)
    • 或通过Comparator自定义排序
  • 特点
    • 查找、插入、删除时间复杂度O(log n)
    • 保持元素有序

七、集合框架性能比较

1. List实现比较

操作ArrayListLinkedList
get(int)O(1)O(n)
add(E)平均O(1)O(1)
add(int, E)O(n)O(1)
remove(int)O(n)O(1)
内存占用较小(仅数组)较大(节点开销)

2. Set实现比较

特性HashSetLinkedHashSetTreeSet
底层实现HashMapLinkedHashMapTreeMap
顺序无序插入顺序自然/自定义排序
时间复杂度O(1)O(1)O(log n)
线程安全

3. Map实现比较

特性HashMapLinkedHashMapTreeMapHashtable
底层实现数组+链表+红黑树链表+哈希表红黑树数组+链表
顺序无序插入/访问顺序键排序无序
线程安全
允许null

八、线程安全集合

1. 传统线程安全集合

Vector和Hashtable
// 线程安全但性能较差
Vector<String> vector = new Vector<>();
Hashtable<String, Integer> hashtable = new Hashtable<>();
Collections.synchronizedXXX
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
Map<String, Integer> syncMap = Collections.synchronizedMap(new HashMap<>());

2. Java 5+并发集合

CopyOnWriteArrayList
// 写时复制,适合读多写少场景
List<String> cowList = new CopyOnWriteArrayList<>();
ConcurrentHashMap
// 分段锁实现高并发
Map<String, Integer> concurrentMap = new ConcurrentHashMap<>();
BlockingQueue
// 阻塞队列
BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
queue.put("item");  // 阻塞直到空间可用
String item = queue.take();  // 阻塞直到元素可用

九、最佳实践

1. 集合选择策略

  • 需要快速随机访问:ArrayList
  • 频繁插入删除:LinkedList
  • 去重存储:HashSet/LinkedHashSet/TreeSet
  • 键值存储:HashMap/LinkedHashMap/TreeMap
  • 线程安全:ConcurrentHashMap/CopyOnWriteArrayList

2. 性能优化建议

  1. 初始化合适容量

    new ArrayList<>(100);  // 避免频繁扩容
    new HashMap<>(32, 0.75f);
    
  2. 使用forEach代替迭代器

    // Java 8+
    list.forEach(System.out::println);
    map.forEach((k, v) -> System.out.println(k + ": " + v));
    
  3. 避免在循环中修改集合

    // 错误方式 - 可能抛出ConcurrentModificationException
    for (String item : list) {if (condition) {list.remove(item);}
    }// 正确方式 - 使用迭代器
    Iterator<String> it = list.iterator();
    while (it.hasNext()) {if (condition) {it.remove();}
    }
    

3. 常见陷阱

  1. Arrays.asList返回固定大小List

    List<String> list = Arrays.asList("A", "B", "C");
    // list.add("D"); // 抛出UnsupportedOperationException
    
  2. 集合元素可变性问题

    Set<Date> dates = new HashSet<>();
    Date now = new Date();
    dates.add(now);
    now.setTime(now.getTime() + 1000); // 修改后影响集合行为
    
  3. equals和hashCode不一致

    class Person {String name;// 如果只重写equals不重写hashCode,会导致HashSet/HashMap行为异常
    }
    

十、Java 8-17集合新特性

1. Java 8增强

  • Stream API:函数式集合操作
  • HashMap性能提升:链表转红黑树
  • 新增方法
    map.computeIfAbsent(key, k -> new ArrayList<>()).add(value);
    list.removeIf(e -> e.length() > 5);
    

2. Java 9增强

  • 工厂方法创建不可变集合
    List<String> list = List.of("A", "B", "C");
    Set<Integer> set = Set.of(1, 2, 3);
    Map<String, Integer> map = Map.of("A", 1, "B", 2);
    

3. Java 10增强

  • copyOf创建不可变集合
    List<String> copy = List.copyOf(originalList);
    

4. Java 16增强

  • Stream.toList()简化
    List<String> list = stream.toList(); // 替代collect(Collectors.toList())
    

通过深入理解Java集合框架的设计原理和使用方法,开发者可以编写出更高效、更健壮的代码。集合框架是Java编程中最常用的工具之一,掌握其特性和最佳实践对提高开发效率至关重要。

相关文章:

  • matplotlib1-画成对数据图
  • 类的六个默认成员函数
  • ssrf与xxe
  • typescript学习笔记(全)
  • 避免事件“穿透”——Vue 中事件冒泡的理解与解决方案
  • HarmonyOS 框架基础知识
  • 力扣hot100 91-100记录
  • 如何构建高效的接口自动化测试框架?
  • Java转Go日记(十二):Channel
  • Java for循环中,如何在内循环跳出外循环?
  • MySQL 事务(详细版)
  • 2025五一杯数学建模竞赛思路助攻预定
  • 【Java面试笔记:进阶】18.什么情况下Java程序会产生死锁?如何定位、修复?
  • java多线程(3.0)
  • 【25软考网工】第三章(3)虚拟局域网VLAN
  • 拆解华为Pura X新发现:“仿生”散热与钛合金“骨架”
  • 每日算法——快乐数、两数之和
  • C++学习:六个月从基础到就业——STL算法(二)排序与变序算法
  • 《AI大模型应知应会100篇》 第36篇:RAG技术入门:检索增强生成原理及实现
  • 施磊老师基于muduo网络库的集群聊天服务器(六)
  • 30天内三访中国,宝马董事长:没有一家公司可以在全球价值链外独立运行
  • 华夏银行青岛分行另类处置不良债权,德州近百亩土地被神奇操作抵押贷款
  • 中海宏洋集团4.17亿元竞得浙江绍兴宅地,溢价率20.87%
  • 夜读丨一条鱼的使命
  • 灰鹦鹉爆粗口三年未改?云南野生动物园:在持续引导
  • 央行研究局局长答澎湃:持续优化跨境金融服务政策工具箱,有效支持企业走出去