集合家族详情

一、Java集合框架全景图

1.1 核心接口层次结构

复制代码
graph TD
    A[Iterable] --> B[Collection]
    B --> C1[List]
    B --> C2[Set]
    B --> C3[Queue]
    C1 --> D1[ArrayList]
    C1 --> D2[LinkedList]
    C2 --> E1[HashSet]
    C2 --> E2[TreeSet]
    C3 --> F1[PriorityQueue]
    G[Map] --> H1[HashMap]
    G --> H2[TreeMap]
    G --> H3[ConcurrentHashMap]

1.2 核心接口说明

接口 特点 典型实现类
List 有序、可重复 ArrayList, LinkedList
Set 无序、唯一 HashSet, TreeSet
Queue 先进先出(FIFO)或优先级队列 LinkedList, PriorityQueue
Map 键值对存储 HashMap, TreeMap
Deque 双端队列 ArrayDeque

二、List家族深度剖析

2.1 ArrayList vs LinkedList

特性 ArrayList LinkedList
底层结构 动态数组 双向链表
随机访问速度 O(1) O(n)
插入删除性能 尾部O(1),中间O(n) 头尾O(1),中间O(n)
内存占用 连续内存,空间浪费少 每个元素额外存储两个指针
最佳场景 高频查询+尾部操作 频繁插入删除(尤其是中间)

代码示例:初始化与遍历

java 复制代码
// ArrayList初始化
List<String> arrayList = new ArrayList<>();
arrayList.add("Java");
arrayList.add("Python");

// LinkedList初始化
List<String> linkedList = new LinkedList<>();
linkedList.add("C++");
linkedList.addFirst("Go");  // 链表特有方法

// 通用遍历方式(JDK8+)
arrayList.forEach(System.out::println);

三、Set家族的奥秘

3.1 HashSet vs TreeSet

特性 HashSet TreeSet
底层实现 HashMap 红黑树
元素顺序 无序 自然顺序或Comparator排序
时间复杂度 添加/删除/查找平均O(1) 所有操作O(log n)
允许null值 否(除非Comparator支持)

代码示例:自定义对象的HashSet使用

java 复制代码
class Student {
    String id;
    String name;
    // 必须重写equals和hashCode!
    @Override
    public boolean equals(Object o) { /*...*/ }
    @Override
    public int hashCode() { /*...*/ }
}

Set<Student> students = new HashSet<>();
students.add(new Student("1001", "Alice"));

四、Map家族的王者之争

4.1 HashMap底层原理(JDK8+)

  • 数组+链表+红黑树结构

  • 默认负载因子0.75,扩容阈值=容量×负载因子

  • 哈希冲突解决:链表长度≥8时转红黑树,≤6时退化为链表

PUT操作流程示意图:

java 复制代码
ConcurrentMap<String, Integer> scores = new ConcurrentHashMap<>();
scores.compute("Alice", (k, v) -> (v == null) ? 1 : v + 1);

五、高级话题与性能优化

5.1 集合初始化容量优化

  • ArrayList:预估数据量避免频繁扩容(默认容量10)

  • HashMap:设置初始容量=预期元素数/0.75 + 1

    java 复制代码
    // 优化示例:预期存储1000个元素
    new HashMap<>( (int)(1000/0.75) + 1 );

5.2 遍历方式的性能对比

遍历方式 ArrayList LinkedList HashSet
for循环 最快 极慢 不支持
迭代器
forEach+lambda

5.3 不可变集合(Java 9+)

java 复制代码
List<String> immutableList = List.of("A", "B", "C");
Set<Integer> immutableSet = Set.of(1, 2, 3);
Map<String, Integer> immutableMap = Map.of("Key1", 1, "Key2", 2);

六、常见问题与陷阱

6.1 ConcurrentModificationException

错误示例:

java 复制代码
List<String> list = new ArrayList<>(Arrays.asList("A", "B"));
for (String s : list) {
    if ("B".equals(s)) {
        list.remove(s);  // 抛出异常!
    }
}

解决方案:

  • 使用迭代器的remove()方法

  • 使用CopyOnWriteArrayList

  • 使用Stream过滤(Java8+)

6.2 hashCode()与equals()的契约

  • 规则1 :两个对象相等(equals()返回true)→ 必须具有相同的hashCode()

  • 规则2hashCode()相同的对象不一定相等

  • 违反后果:在HashSet/HashMap中出现重复元素或丢失元素

七、最佳实践总结

  1. 选择集合类型的三要素

    • 是否需要排序?

    • 是否需要唯一性?

    • 主要操作类型(查询/插入/删除)?

  2. 线程安全策略

    • 无竞争:普通集合

    • 低竞争:Collections.synchronizedXXX()

    • 高并发:ConcurrentHashMap, CopyOnWriteArrayList

  3. 性能黄金法则

    • 预估容量减少扩容

    • 避免在循环中频繁创建迭代器

    • 复杂对象实现高效的hashCode()方法

相关推荐
风生u3 小时前
activiti7 详解
java
玄同7653 小时前
我的 Trae Skill 实践|使用 UV 工具一键搭建 Python 项目开发环境
开发语言·人工智能·python·langchain·uv·trae·vibe coding
岁岁种桃花儿3 小时前
SpringCloud从入门到上天:Nacos做微服务注册中心(二)
java·spring cloud·微服务
Word码3 小时前
[C++语法] 继承 (用法详解)
java·jvm·c++
Yorlen_Zhang3 小时前
Python Tkinter Text 控件完全指南:从基础编辑器到富文本应用
开发语言·python·c#
lxl13073 小时前
C++算法(1)双指针
开发语言·c++
TT哇3 小时前
【实习 】银行经理端两个核心功能的开发与修复(银行经理绑定逻辑修复和线下领取扫码功能开发)
java·vue.js
逝水如流年轻往返染尘3 小时前
Java中的数组
java
不绝1913 小时前
C#进阶:预处理指令/反射,Gettype,Typeof/关键类
开发语言·c#
无小道3 小时前
Qt-qrc机制简单介绍
开发语言·qt