Java集合马戏团:List、Set、Map大狂欢

Java集合马戏团:List、Set、Map大狂欢

List系列:有序的队列大师

1. ArrayList - 数组型"快枪手"

List<String> list = new ArrayList<>(); // 默认容量10
// 悄悄增长的秘密
int newCapacity = oldCapacity + (oldCapacity >> 1); // 1.5倍

特点:

  • 背后是动态数组 ️
  • 按序号访问速度堪比闪电 ⚡(O(1))

适用场景:

  • 频繁按索引访问
  • 需要遍历的只读数据
  • 95%的日常List需求

2. LinkedList - 链表型"杂技演员"

   List<String> list = new LinkedList<>(); // 不需要扩容

特点:

  • 头尾插入/删除特技 (O(1))
  • 随机访问像蜗牛 (O(n))

幽默时刻:

  • ArrayList:“我能快速找到第100个元素!”
  • LinkedList:“我能倒立插入元素,你能吗?”

ArrayList vs LinkedList 插入对比:

// 头部插入10000次
ArrayList: 152ms
LinkedList: 3ms
// LinkedList胜出!

// 随机访问第5000个元素
ArrayList: 0.01ms  
LinkedList: 12ms
// ArrayList碾压!

3. Vector - 古老的"钢铁侠"

List<String> list = new Vector<>(); // 默认扩容2倍

特点:

  • 线程安全但性能堪忧 ️
  • 基本被ArrayList+Collections.synchronizedList取代

怀旧场景:

  • 维护祖传代码时
  • 需要给实习生讲历史课时

Set系列:不重复的魔法袋

1. HashSet - 闪电查找师

Set<String> set = new HashSet<>(); // 底层是HashMap

魔法原理:

  • 用hashCode()快速定位
  • 实际存放于HashMap的key中

碰撞实验:

public class HashSetTest {
    public static void main(String[] args) {
        String s1 = "通话";
        String s2 = "重地";
        System.out.println(s1.hashCode() == s2.hashCode()); // true!
    }
}

不同的字符串可能有相同的hashCode,就像不同的人可能身份证尾号相同~

2. LinkedHashSet - 有记忆的魔法师

Set<String> set = new LinkedHashSet<>(); // 记住插入顺序

特点:

  • 既去重又保序
  • 比HashSet稍慢但更可控

适用场景:

  • 需要去重又要保持顺序
  • 实现LRU缓存的好帮手

️ Map系列:钥匙保管员

1. HashMap - 散列魔术师

Map<String, Integer> map = new HashMap<>(); // 默认加载因子0.75

核心原理:

  • 计算key的hashCode
  • 通过(n-1) & hash确定桶位置
  • 链表长度>8转红黑树

幽默时刻:

  • 面试官:“HashMap线程安全吗?”
  • 你:“不安全,但ConcurrentHashMap可以救场!”

2. LinkedHashMap - 带记事本的保管员

Map<String, Integer> map = new LinkedHashMap<>(16, 0.75f, true);
// accessOrder=true实现LRU

特点:

  • 继承HashMap的所有能力
  • 额外维护插入/访问顺序

实战场景:

// 实现简易LRU缓存
Map<String, Object> cache = new LinkedHashMap<>(100, 0.75f, true) {
    private boolean removeEldestEntry(Map.Entry eldest) {
        return size() > 100;
    }
};

3. ConcurrentHashMap - 多线程安全卫士

   Map<String, Integer> map = new ConcurrentHashMap<>();

并发秘籍:

  • JDK7:分段锁
  • JDK8+:CAS+synchronized优化

性能对比:

Hashtable:全局锁 → 慢如蜗牛
ConcurrentHashMap:细粒度锁 → 快如闪电

终极选择指南

需求 推荐选择 原因
快速随机访问 ArrayList 数组结构速度飞起
频繁增删 LinkedList 链表操作O(1)
去重存储 HashSet 哈希查找O(1)
去重且保序 LinkedHashSet 双向链表记录顺序
一般键值存储 HashMap 综合性能最佳
需要访问顺序 LinkedHashMap 维护插入/访问顺序
高并发环境 ConcurrentHashMap 分段锁降低竞争

总结

  • 默认选择:无脑用ArrayList + HashMap组合能满足80%需求
  • 线程安全:用Collections.synchronizedList包装,或直接上ConcurrentHashMap
  • 内存敏感:考虑ArrayDeque替代LinkedList
  • 有序需求:LinkedHashSet/LinkedHashMap是你的好朋友

你可能感兴趣的:(Java那些事,java,list,开发语言)