集合家族详情

一、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()方法

相关推荐
wjs20242 小时前
状态模式(State Pattern)
开发语言
我命由我123452 小时前
Kotlin 数据容器 - List(List 概述、创建 List、List 核心特性、List 元素访问、List 遍历)
java·开发语言·jvm·windows·java-ee·kotlin·list
liulilittle2 小时前
C++ TAP(基于任务的异步编程模式)
服务器·开发语言·网络·c++·分布式·任务·tap
励志要当大牛的小白菜3 小时前
ART配对软件使用
开发语言·c++·qt·算法
武子康4 小时前
Java-80 深入浅出 RPC Dubbo 动态服务降级:从雪崩防护到配置中心秒级生效
java·分布式·后端·spring·微服务·rpc·dubbo
爱装代码的小瓶子6 小时前
数据结构之队列(C语言)
c语言·开发语言·数据结构
YuTaoShao7 小时前
【LeetCode 热题 100】131. 分割回文串——回溯
java·算法·leetcode·深度优先
源码_V_saaskw7 小时前
JAVA图文短视频交友+自营商城系统源码支持小程序+Android+IOS+H5
java·微信小程序·小程序·uni-app·音视频·交友
Maybe_ch7 小时前
.NET-键控服务依赖注入
开发语言·c#·.net
超浪的晨7 小时前
Java UDP 通信详解:从基础到实战,彻底掌握无连接网络编程
java·开发语言·后端·学习·个人开发