深入理解 Java 集合框架:HashSet、HashMap、Hashtable、LinkedHashSet、TreeSet 和 ConcurrentHashMap 的特点、应用场景与性能对比

目录

1. HashSet

2. HashMap

3. Hashtable

4. LinkedHashSet

5. TreeSet

6. ConcurrentHashMap


1. HashSet

  • 定义HashSet 是一个 无序集合,实现了 Set 接口,基于 哈希表 实现。它不允许有重复的元素,集合中的元素是唯一的。

  • 特点:

    • 无序:集合中的元素没有顺序。

    • 不允许重复:如果向集合中添加一个已经存在的元素,添加操作会失败。

    • 性能:提供 O(1) 平均时间复杂度的插入、删除和查找操作。

    • 不保证顺序:元素的顺序是不确定的。

  • 适用场景:当你需要快速查找元素,且不关心元素顺序时,HashSet 是一个理想选择。

  • 常用方法:

    • add(T element):向集合中添加元素。

    • remove(Object o):从集合中删除指定元素。

    • contains(Object o):检查集合中是否包含指定元素。

    • size():返回集合中元素的数量。

HashSet<Integer> set = new HashSet<>();
set.add(1);
set.add(2);
set.add(3);
set.add(2);  // 不会被添加,因重复元素

2. HashMap

  • 定义HashMap 是一个 键值对集合,基于 哈希表 实现,存储的是 key-value 对,其中的 key 是唯一的,但 value 可以重复。

  • 特点:

    • 无序HashMap 中的元素没有顺序。

    • 唯一的键:每个键在 HashMap 中都是唯一的,不能重复;如果插入一个相同的键,原值会被覆盖。

    • 允许 null 值HashMap 允许一个 null 键和多个 null 值。

    • 性能:提供 O(1) 平均时间复杂度的插入、删除和查找操作。

  • 适用场景:当你需要根据一个 快速查找对应的 时,使用 HashMap

  • 常用方法:

    • put(K key, V value):插入键值对。

    • get(Object key):根据键获取值。

    • remove(Object key):删除键值对。

    • containsKey(Object key):检查是否包含某个键。

    • size():返回键值对数量。

HashMap<String, Integer> map = new HashMap<>();
map.put("apple", 5);
map.put("banana", 3);
map.put("apple", 10);  // 更新键 "apple" 的值

3. Hashtable

  • 定义Hashtable 是一个 键值对集合,基于 哈希表 实现,类似于 HashMap,但是有一些区别。它已经被标记为不推荐使用的类,主要是由于线程安全的问题和与现代 Map 接口的差距。

  • 特点:

    • 线程安全Hashtable 是线程安全的,它的方法是同步的,适合多线程环境下使用。

    • 不允许 null 键或 null 值Hashtable 不能插入 null 键或 null 值。

    • 性能:由于方法是同步的,相对于 HashMap,它在单线程环境下会有更差的性能。

    • 已不推荐使用:HashTable 已经不再推荐使用,建议使用 HashMapConcurrentHashMap 替代。

  • 适用场景:在 多线程 环境下需要线程安全的哈希表时使用,但通常推荐使用 ConcurrentHashMap

4. LinkedHashSet

  • 定义LinkedHashSetHashSet 的一个子类,它是基于哈希表和双向链表实现的,提供了 插入顺序 的保障。

  • 特点:

    • 有序LinkedHashSet 保证元素的插入顺序。即元素的顺序是按照它们被插入的顺序排列的。

    • 不允许重复元素:跟 HashSet 一样,LinkedHashSet 也不允许重复元素。

    • 性能:虽然插入顺序被保持,但 LinkedHashSet 的性能开销稍微大于 HashSet,但是在大多数情况下,它提供了与 HashSet 类似的性能。

  • 适用场景:当你需要一个无重复元素的集合,并且要保持元素的插入顺序时,使用 LinkedHashSet

  • 常用方法:

    • add(T element):向集合中添加元素。

    • remove(Object o):从集合中删除指定元素。

    • contains(Object o):检查集合中是否包含指定元素。

LinkedHashSet<Integer> linkedSet = new LinkedHashSet<>();
linkedSet.add(1);
linkedSet.add(2);
linkedSet.add(3);
linkedSet.add(2);  // 不会被添加,因重复元素
// 保持插入顺序

5. TreeSet

  • 定义TreeSet 是基于 红黑树(一种自平衡二叉搜索树)实现的 Set,它是有序的,自动对元素进行排序。

  • 特点:

    • 有序TreeSet 会根据元素的自然顺序或者通过构造函数传入的比较器对元素进行排序。

    • 不允许重复元素:像 HashSetLinkedHashSet 一样,TreeSet 也不允许重复元素。

    • 性能:由于其底层是红黑树,插入、删除和查找操作的时间复杂度是 O(log n),比 HashSet 更慢,但提供了排序的能力。

  • 适用场景:当你需要一个排序的集合时,TreeSet 是最佳选择。

  • 常用方法:

    • add(T element):向集合中添加元素。

    • remove(Object o):从集合中删除指定元素。

    • contains(Object o):检查集合中是否包含指定元素。

    • first():返回集合中的第一个元素。

    • last():返回集合中的最后一个元素。

TreeSet<Integer> treeSet = new TreeSet<>();
treeSet.add(3);
treeSet.add(1);
treeSet.add(2);
// 自动排序:1, 2, 3

6. ConcurrentHashMap

  • 定义ConcurrentHashMap 是一个线程安全的 哈希表 实现,它允许多个线程并发地读写数据。

  • 特点:

    • 线程安全:支持多个线程并发操作,不需要像 Hashtable 那样对整个数据结构加锁,而是采用了 分段锁,使得并发性能更好。

    • 允许 null 值ConcurrentHashMap 允许 null 值,但不允许 null 键。

    • 性能:相较于 HashtableConcurrentHashMap 提供了更高的并发性能。

  • 适用场景:适用于多线程环境下进行并发操作的哈希表。

  • 常用方法:

    • put(K key, V value):插入键值对。

    • get(Object key):根据键获取值。

    • remove(Object key):删除键值对。

ConcurrentHashMap<String, Integer> concurrentMap = new ConcurrentHashMap<>();
concurrentMap.put("apple", 5);
concurrentMap.put("banana", 3);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值