Java 集合框架 (Collections Framework) 大纲

Java 集合框架 (Collections Framework) 是 Java 平台提供的一组接口、实现类和算法,用于存储、操作和管理对象集合。 它是 Java 编程中最核心、最常用的 API 之一。

一、 集合框架概述 (Overview)

  1. 定义:

    • 集合框架是一个统一的架构,用于表示和操作集合,允许它们独立于表示的细节进行操作。
    • 集合框架提供了一组通用的接口和类,用于存储不同类型的对象,并提供了对这些对象进行添加、删除、查找、遍历、排序等操作。
  2. 优点:

    • 减少编程工作量: 提供了现成的、高效的数据结构和算法,无需从头开始编写。
    • 提高程序性能: 集合框架中的实现类经过了优化,具有良好的性能。
    • 提高代码可读性和可维护性: 使用统一的接口和类,使代码更易于理解和维护。
    • 促进代码复用: 集合框架中的接口和类可以在不同的程序中重复使用。
    • 提供互操作性: 基于接口的集合框架允许不同类型的集合之间进行互操作。
  3. 组成部分:

    • 接口 (Interfaces): 定义了集合的通用行为,例如 Collection, List, Set, Map, Queue, Deque 等。
    • 实现类 (Implementations): 提供了接口的具体实现,例如 ArrayList, LinkedList, HashSet, TreeSet, HashMap, TreeMap 等。
    • 算法 (Algorithms): 提供了一些常用的算法,例如排序、查找、打乱顺序等,这些算法可以用于操作各种类型的集合。

二、 核心接口 (Core Interfaces)

Java 集合框架的核心接口主要分为两大类:

  1. Collection 接口:

    • Collection 接口是所有集合接口的根接口,它定义了集合的基本操作,例如添加元素、删除元素、判断是否包含元素、获取集合大小、遍历集合等。
    • Collection 接口的主要子接口:
      • List 接口: 有序集合,允许重复元素。
      • Set 接口: 无序集合,不允许重复元素。
      • Queue 接口: 队列,通常用于存储等待处理的元素(FIFO - 先进先出)。
      • Deque 接口: 双端队列,可以在两端添加和删除元素。
  2. Map 接口:

    • Map 接口用于存储键值对 (key-value pairs),每个键映射到一个值。
    • Map 接口中的键不能重复,值可以重复。
    • Map 接口的主要实现类:
      • HashMap
      • TreeMap
      • LinkedHashMap

接口层次结构 (简化版):

                          Collection<E>
                              /  |  \
                             /   |   \
                            /    |    \
                           /     |     \
                      List<E>  Set<E>  Queue<E>
                      /   \      |       /  \
                     /     \     |      /    \
           ArrayList  LinkedList HashSet Deque<E>
                                   |       |
                                TreeSet  ArrayDeque
                                         PriorityQueue


                                Map<K, V>
                               /    |    \
                              /     |     \
                          HashMap  TreeMap  LinkedHashMap

三、 常用接口和实现类详解

  1. Collection<E> 接口:

    • 常用方法:
      • add(E e): 添加元素。
      • addAll(Collection<? extends E> c): 添加另一个集合中的所有元素。
      • remove(Object o): 删除元素。
      • removeAll(Collection<?> c): 删除另一个集合中包含的所有元素。
      • retainAll(Collection<?> c): 仅保留此集合中包含在另一个集合中的元素(交集)。
      • clear(): 删除所有元素。
      • contains(Object o): 判断是否包含指定元素。
      • containsAll(Collection<?> c): 判断是否包含另一个集合中的所有元素。
      • isEmpty(): 判断集合是否为空。
      • size(): 返回集合中元素的数量。
      • iterator(): 返回一个用于遍历集合的迭代器。
      • toArray(): 将集合转换为数组。
      • toArray(T[] a): 将集合转换为指定类型的数组。
  2. List<E> 接口:

    • 特点: 有序集合,允许重复元素。 可以通过索引访问元素。

    • 常用方法 (除了 Collection 接口的方法外):

      • get(int index): 获取指定索引处的元素。
      • set(int index, E element): 替换指定索引处的元素。
      • add(int index, E element): 在指定索引处插入元素。
      • remove(int index): 删除指定索引处的元素。
      • indexOf(Object o): 返回指定元素第一次出现的索引。
      • lastIndexOf(Object o): 返回指定元素最后一次出现的索引。
      • subList(int fromIndex, int toIndex): 返回指定范围的子列表。
      • listIterator(): 返回一个列表迭代器,可以双向遍历列表,并修改列表。
    • 常用实现类:

      • ArrayList: 基于动态数组实现,查询快,插入/删除慢 (尤其是在中间插入/删除)。 非线程安全。
      • LinkedList: 基于双向链表实现,插入/删除快 (尤其是在中间插入/删除),查询慢。 非线程安全。
      • Vector: 类似于 ArrayList,但线程安全 (方法都使用 synchronized 修饰)。 性能较低。
      • Stack: 继承自Vector,表示栈。
  3. Set<E> 接口:

    • 特点: 无序集合,不允许重复元素。
    • 常用方法 (与 Collection 接口基本相同):
    • 常用实现类:
      • HashSet: 基于哈希表实现,无序,查找、添加、删除速度快。 非线程安全。
      • LinkedHashSet: 基于哈希表和链表实现,按照插入顺序排序。 非线程安全。
      • TreeSet: 基于红黑树实现,有序 (可以按照自然顺序或自定义比较器排序)。 非线程安全。
  4. Queue<E> 接口:

    • 特点: 队列,通常用于存储等待处理的元素,遵循 FIFO (先进先出) 原则。

    • 常用方法:

      • add(E e) / offer(E e): 添加元素到队尾 (前者在队列满时抛出异常,后者返回 false)。
      • remove() / poll(): 移除并返回队头元素 (前者在队列为空时抛出异常,后者返回 null)。
      • element() / peek(): 返回队头元素,但不移除 (前者在队列为空时抛出异常,后者返回 null)。
    • 常用实现类:

      • LinkedList: 也实现了 Queue 接口,可以用作队列。
      • PriorityQueue: 优先级队列,元素按照优先级排序。
      • ArrayBlockingQueue: 基于数组的有界阻塞队列。
      • LinkedBlockingQueue: 基于链表的可选有界阻塞队列。
      • PriorityBlockingQueue: 无界阻塞优先级队列。
      • DelayQueue: 延迟队列,元素只有在延迟时间到期后才能被取出。
      • SynchronousQueue: 同步队列,每个插入操作必须等待另一个线程的移除操作,反之亦然。
  5. Deque<E> 接口:

    • 特点: 双端队列 (Double Ended Queue),可以在两端添加和删除元素。

    • 常用方法:

      • addFirst(E e), offerFirst(E e)
      • addLast(E e), offerLast(E e)
      • removeFirst(), pollFirst()
      • removeLast(), pollLast()
      • getFirst(), peekFirst()
      • getLast(), peekLast()
    • 常用实现类:

      • LinkedList: 也实现了Deque接口。
      • ArrayDeque: 基于数组实现的双端队列。
  6. Map<K, V> 接口:

    • 特点: 存储键值对 (key-value pairs),键不能重复,值可以重复。

    • 常用方法:

      • put(K key, V value): 添加键值对。
      • get(Object key): 根据键获取值。
      • remove(Object key): 根据键删除键值对。
      • containsKey(Object key): 判断是否包含指定的键。
      • containsValue(Object value): 判断是否包含指定的值。
      • isEmpty(): 判断 Map 是否为空。
      • size(): 返回 Map 中键值对的数量。
      • keySet(): 返回所有键的 Set 集合。
      • values(): 返回所有值的 Collection 集合。
      • entrySet(): 返回所有键值对的 Set 集合 (每个元素是一个 Map.Entry 对象)。
    • 常用实现类:

      • HashMap: 基于哈希表实现,无序,查找、添加、删除速度快。 非线程安全。 允许 null 键和 null 值。
      • TreeMap: 基于红黑树实现,有序 (可以按照自然顺序或自定义比较器排序)。 非线程安全。
      • LinkedHashMap: 基于哈希表和链表实现,按照插入顺序或访问顺序排序。 非线程安全。
      • Hashtable: 类似于 HashMap,但线程安全 (方法都使用 synchronized 修饰)。 性能较低。 不允许 null 键和 null 值。
      • ConcurrentHashMap: 线程安全的 HashMap,使用分段锁 (Segment Locking) 或 CAS 操作实现高效的并发访问。

四、常用算法 (Collections Class)

java.util.Collections 类提供了一组静态方法,用于操作集合:

  • 排序: sort(List<T> list), sort(List<T> list, Comparator<? super T> c)
  • 查找: binarySearch(List<? extends Comparable<? super T>> list, T key), binarySearch(List<? extends T> list, T key, Comparator<? super T> c)
  • 最大/最小值: max(Collection<? extends T> coll), min(Collection<? extends T> coll), max(Collection<? extends T> coll, Comparator<? super T> comp), min(Collection<? extends T> coll, Comparator<? super T> comp)
  • 反转: reverse(List<?> list)
  • 打乱顺序: shuffle(List<?> list)
  • 填充: fill(List<? super T> list, T obj)
  • 复制: copy(List<? super T> dest, List<? extends T> src)
  • 同步: synchronizedCollection(Collection<T> c), synchronizedList(List<T> list), synchronizedSet(Set<T> s), synchronizedMap(Map<K,V> m) (用于创建线程安全的集合)
  • 不可修改: unmodifiableCollection(Collection<? extends T> c), unmodifiableList(List<? extends T> list), unmodifiableSet(Set<? extends T> s), unmodifiableMap(Map<? extends K,? extends V> m) (用于创建不可修改的集合)

五、迭代器 (Iterator)

  • Iterator<E> 接口: 用于遍历集合中的元素。

    • hasNext(): 判断是否还有下一个元素。
    • next(): 返回下一个元素。
    • remove(): 删除迭代器最后一次返回的元素 (可选操作,并非所有迭代器都支持)。
  • ListIterator<E> 接口: List 接口特有的迭代器,支持双向遍历,并可以修改列表。

    • hasPrevious(): 判断是否还有上一个元素。
    • previous(): 返回上一个元素。
    • nextIndex(): 返回下一个元素的索引。
    • previousIndex(): 返回上一个元素的索引。
    • set(E e): 替换迭代器最后一次返回的元素。
    • add(E e): 在迭代器当前位置插入一个元素。
  • 增强 for 循环 (for-each 循环): 简化了集合的遍历. 本质上是使用了 Iterator.

    List<String> list = Arrays.asList("a", "b", "c");
    for (String s : list) {
        System.out.println(s);
    }
    

六、泛型 (Generics)

  • 集合框架广泛使用了泛型,可以指定集合中存储的元素类型,提高类型安全性和代码可读性。
  • 例如:List<String> 表示一个只能存储 String 类型元素的列表。
  • 泛型的好处:
    • 类型安全: 在编译时检查类型错误,避免运行时类型转换异常。
    • 代码可读性: 代码更清晰,更容易理解。
    • 代码复用: 可以编写更通用的代码,处理不同类型的集合。

七、并发集合 (Concurrent Collections)

java.util.concurrent 包提供了一组线程安全的集合类,用于多线程环境:

  • ConcurrentHashMap: 线程安全的 HashMap
  • CopyOnWriteArrayList: 线程安全的 List,适用于读多写少的场景。
  • CopyOnWriteArraySet: 线程安全的 Set,适用于读多写少的场景。
  • ConcurrentLinkedQueue: 线程安全的无界队列。
  • ConcurrentLinkedDeque: 线程安全的无界双端队列。
  • 阻塞队列 (BlockingQueue): ArrayBlockingQueue, LinkedBlockingQueue, PriorityBlockingQueue, DelayQueue, SynchronousQueue

八、最佳实践

  1. 选择合适的集合类型: 根据你的需求选择最合适的集合接口和实现类。 考虑以下因素:

    • 是否需要有序?
    • 是否允许重复元素?
    • 是否需要根据键查找值?
    • 是否需要线程安全?
    • 插入、删除、查找的频率?
  2. 使用泛型: 始终使用泛型来指定集合中存储的元素类型,提高类型安全性。

  3. 面向接口编程: 使用接口类型(例如 List, Set, Map)声明变量,而不是使用具体的实现类类型。

  4. 使用增强 for 循环: 优先使用增强 for 循环遍历集合,代码更简洁。

  5. 注意并发问题: 在多线程环境下,使用线程安全的集合类,或者使用同步机制来保护非线程安全的集合。

  6. 避免在迭代过程中修改集合: 在使用迭代器遍历集合时,不要直接修改集合的结构(例如添加或删除元素),否则可能会抛出 ConcurrentModificationException。 可以使用迭代器的 remove() 方法删除元素,或者使用 ListIterator 修改列表。

  7. 了解集合的性能特征: 不同的集合实现类具有不同的性能特征,了解这些特征可以帮助我们选择最合适的集合。

  8. 使用 Collections 工具类: 充分利用 Collections 工具类提供的各种静态方法,简化集合操作。

  9. 合理设置集合的初始容量: 对于 ArrayListHashMap 等基于数组的集合,在创建时指定一个合适的初始容量,可以减少扩容操作,提高性能。

  10. 注意 null 值: 一些集合 (例如HashMap, ArrayList) 允许null值, 一些集合 (例如 TreeMap, Hashtable) 不允许。

总结

Java 集合框架是 Java 编程中非常重要的一个部分,它提供了一组强大、灵活、高效的工具来处理对象集合。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰糖心书房

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值