Bootstrap

Java集合概述(Ⅱ)

基础

之前写过一个比较粗糙的版本:Java集合概述

本文章补充了Java集合体系当中的一些细节

Collection接口的方法

在这里插入图片描述

List接口,Set接口都会继承这些方法

List接口

特点:存取顺序有序(因为有下标),可重复(元素之间由下标区分)

List的中间插入/删除方法会导致后续元素移动

在这里插入图片描述
ListIterator相比于Iterator高级的地方是可以反向遍历(因为list有下标),而且可以执行add并发操作(但是add的结果本次遍历不生效,下一次可以

Java 中的集合框架(Collection Framework)是 Java 标准库的一部分,提供了用于存储和操作一组对象的统一架构。集合框架的核心接口是 java.util.Collection,它是所有集合类的基础接口。以下是 Collection 接口及其主要实现类的详细介绍。


Collection 接口

Collection 是集合框架的根接口,定义了集合的基本操作,如添加、删除、遍历等。它继承自 Iterable 接口,因此所有集合类都支持迭代操作。

主要方法

  • 添加元素:
    • boolean add(E e): 添加一个元素。
    • boolean addAll(Collection<? extends E> c): 添加一个集合中的所有元素。
  • 删除元素:
    • boolean remove(Object o): 删除指定元素。
    • boolean removeAll(Collection<?> c): 删除与指定集合中相同的所有元素。
    • void clear(): 清空集合。
  • 查询操作:
    • boolean contains(Object o): 判断集合是否包含指定元素。
    • boolean containsAll(Collection<?> c): 判断集合是否包含指定集合中的所有元素。
    • boolean isEmpty(): 判断集合是否为空。
    • int size(): 返回集合中元素的数量。
  • 遍历操作:
    • Iterator<E> iterator(): 返回一个迭代器,用于遍历集合。
  • 其他操作:
    • Object[] toArray(): 将集合转换为数组。
    • <T> T[] toArray(T[] a): 将集合转换为指定类型的数组。
    • boolean retainAll(Collection<?> c): 仅保留与指定集合中相同的元素。

Collection 的子接口

Collection 接口有三个主要的子接口:

  1. List: 有序集合,允许重复元素。
  2. Set: 无序集合,不允许重复元素。
  3. Queue: 队列,支持先进先出(FIFO)或其他特定顺序的操作。

List 接口

List 是一个有序集合,允许存储重复元素。它通过索引访问元素,支持按位置插入、删除和修改元素。

主要实现类

  1. ArrayList:

    • 基于动态数组实现。
    • 支持快速随机访问(通过索引)。
    • 插入和删除元素效率较低(需要移动元素)。
    • 线程不安全。
    • 适用场景: 需要频繁访问元素的场景。
  2. LinkedList:

    • 基于双向链表实现。
    • 插入和删除元素效率高(只需修改指针)。
    • 随机访问效率低(需要遍历链表)。
    • 实现了 Deque 接口,可以用作队列或栈。
    • 适用场景: 需要频繁插入和删除元素的场景。
  3. Vector:

    • 基于动态数组实现,与 ArrayList 类似。
    • 线程安全(方法使用 synchronized 修饰)。
    • 性能较低(由于同步开销)。
    • 适用场景: 需要线程安全的场景(已被 Collections.synchronizedList 取代)。
  4. Stack:

    • 继承自 Vector,实现栈数据结构(后进先出,LIFO)。
    • 提供了 pushpoppeek 等栈操作。
    • 适用场景: 需要栈操作的场景(推荐使用 Deque 替代)。

Set 接口

Set 是一个无序集合,不允许存储重复元素。它通常用于去重或判断元素是否存在。

主要实现类

  1. HashSet:

    • 基于哈希表实现。
    • 插入、删除和查找操作的时间复杂度为 O(1)。
    • 不保证元素的顺序。
    • 适用场景: 需要快速查找和去重的场景。
  2. LinkedHashSet:

    • 继承自 HashSet,基于哈希表和链表实现。
    • 保留元素的插入顺序。
    • 适用场景: 需要去重且保留插入顺序的场景。
  3. TreeSet:

    • 基于红黑树实现。
    • 元素按自然顺序或自定义比较器排序。
    • 插入、删除和查找操作的时间复杂度为 O(log n)。
    • 适用场景: 需要有序集合的场景。

Queue 接口

Queue 是一个队列接口,支持先进先出(FIFO)或其他特定顺序的操作。

主要实现类

  1. LinkedList:

    • 实现了 QueueDeque 接口。
    • 可以用作队列或双端队列。
    • 适用场景: 需要队列或双端队列操作的场景。
  2. PriorityQueue:

    • 基于优先级堆实现。
    • 元素按自然顺序或自定义比较器排序。
    • 队首元素总是优先级最高的元素。
    • 适用场景: 需要优先级队列的场景。
  3. ArrayDeque:

    • 基于动态数组实现的双端队列。
    • 性能优于 LinkedList
    • 适用场景: 需要高效的双端队列操作的场景。

其他集合类

除了 Collection 接口及其子接口的实现类,Java 集合框架还提供了一些其他重要的类和接口:

  1. Map 接口:
    • 存储键值对(key-value pairs)。
    • 主要实现类:HashMapLinkedHashMapTreeMap
  2. Collections 工具类:
    • 提供了对集合进行操作的工具方法,如排序、查找、同步等。
  3. Arrays 工具类:
    • 提供了对数组进行操作的工具方法。

总结

  • List: 有序集合,允许重复元素。常用实现类:ArrayListLinkedList
  • Set: 无序集合,不允许重复元素。常用实现类:HashSetLinkedHashSetTreeSet
  • Queue: 队列,支持 FIFO 或其他顺序。常用实现类:LinkedListPriorityQueueArrayDeque

选择合适的集合类取决于具体的需求,如是否需要有序、是否允许重复、是否需要线程安全等。

Java中的Map接口是java.util包的一部分,用于存储键值对(Key-Value)。每个键(Key)唯一对应一个值(Value),键不可重复,但值可以重复。以下是Map接口及其所有实现类的详细介绍:


一、Map接口核心方法

方法说明
put(K key, V value)插入键值对,若键已存在则覆盖旧值
get(Object key)根据键获取值,键不存在返回null
containsKey(Object key)判断是否包含指定键
containsValue(Object value)判断是否包含指定值
remove(Object key)根据键删除键值对
keySet()返回所有键的集合(Set<K>
values()返回所有值的集合(Collection<V>
entrySet()返回所有键值对的集合(Set<Map.Entry<K, V>>
size()返回键值对的数量
clear()清空所有键值对

二、Map的实现类及特点

1. HashMap
  • 数据结构:基于哈希表(数组 + 链表/红黑树,Java 8优化)。
  • 特点
    • 允许null键和null值。
    • 无序,不保证插入顺序。
    • 线程不安全(需外部同步或使用Collections.synchronizedMap)。
    • 查找、插入、删除操作的时间复杂度接近O(1)
  • 适用场景:快速访问键值对,无需排序。
2. LinkedHashMap
  • 数据结构:哈希表 + 双向链表。
  • 特点
    • 继承自HashMap,保留插入顺序或访问顺序(通过构造参数accessOrder控制)。
    • 性能略低于HashMap,但迭代效率高(直接遍历链表)。
  • 适用场景:需要保留插入顺序或LRU缓存(通过覆盖removeEldestEntry实现)。
3. TreeMap
  • 数据结构:基于红黑树(自平衡二叉搜索树)。
  • 特点
    • 键按自然顺序或自定义Comparator排序。
    • 支持导航方法(如firstKey(), ceilingKey(), floorEntry()等)。
    • 查找、插入、删除的时间复杂度为O(log n)
  • 适用场景:需要有序键的场景。
4. Hashtable
  • 数据结构:类似HashMap的哈希表。
  • 特点
    • 线程安全(方法用synchronized修饰),但性能较低。
    • 不允许null键或null值。
    • 已过时,推荐使用ConcurrentHashMap替代。
  • 适用场景:遗留代码或需要同步的Map(不推荐新项目使用)。
5. ConcurrentHashMap
  • 数据结构:分段锁(Java 7)或CAS + synchronized(Java 8优化)。
  • 特点
    • 高并发线程安全,性能优于Hashtable
    • 不允许null键或null值。
    • Java 8后采用更细粒度的锁(每个桶单独锁)。
  • 适用场景:高并发环境下的键值存储。
6. WeakHashMap
  • 数据结构:哈希表,键为弱引用。
  • 特点
    • 当键不再被强引用时,键值对会被自动回收。
    • 适合缓存临时数据。
  • 适用场景:内存敏感的缓存,如临时对象映射。
7. EnumMap
  • 数据结构:数组存储,键为枚举类型。
  • 特点
    • 键必须为枚举类型,内部用枚举顺序优化存储。
    • 性能高效,内存紧凑。
  • 适用场景:枚举键的映射。
8. IdentityHashMap
  • 数据结构:哈希表,使用==代替equals()比较键。
  • 特点
    • 键通过引用相等性(内存地址)判断唯一性。
    • 适用于需要区分对象实例的场景。
  • 适用场景:序列化、深拷贝等特殊场景。
9. Properties(特殊实现)
  • 继承自Hashtable,键值均为String
  • 特点
    • 专用于读取.properties配置文件。
    • 提供load()store()方法操作文件流。
  • 适用场景:配置文件读写。

三、实现类对比表

实现类线程安全允许null键/值排序数据结构时间复杂度
HashMap是/是无序哈希表+链表/红黑树O(1)
LinkedHashMap是/是插入/访问顺序哈希表+双向链表O(1)
TreeMap否/是自然或Comparator红黑树O(log n)
Hashtable否/否无序哈希表O(1)
ConcurrentHashMap否/否无序分段锁或CASO(1)
WeakHashMap是/是无序哈希表(弱引用键)O(1)
EnumMap否/是枚举顺序数组O(1)
IdentityHashMap是/是无序哈希表(引用相等)O(1)

四、选择建议

  • 快速访问HashMap(默认选择)。
  • 有序键TreeMap(自然排序)或LinkedHashMap(插入/访问顺序)。
  • 高并发ConcurrentHashMap(替代Hashtable)。
  • 内存敏感缓存WeakHashMap
  • 枚举键EnumMap
  • 特殊相等性IdentityHashMap

通过理解各实现类的特性,可以更高效地选择合适的Map实现以满足需求。

;