4.1 集合框架 (Collections Framework)


文档摘要

Java 集合框架 (Collections Framework) 核心详解与实战指南 核心摘要:Java 集合框架 (Collections Framework) 是 Java 平台中用于存储和操作对象集合的核心架构。本文深度解析 、 、 、 及 等核心接口与常用实现类(如 、 ),并提供选型指南、迭代遍历方案及并发集合补充,帮助开发者构建高效、可维护的 Java 应用程序。 集合框架概述 Java 集合框架提供了一套统一的架构,用于表示和操作各种类型的集合(如列表、集合、映射等)。它不仅大幅提升了编程效率,还增强了代码的可重用性与可维护性。 集合框架主要由以下核心接口组成: Collection 接口:所有单列集合类型的根接口,定义了添加、删除、判断元素是否存在等基本操作。

Java 集合框架 (Collections Framework) 核心详解与实战指南

核心摘要:Java 集合框架 (Collections Framework) 是 Java 平台中用于存储和操作对象集合的核心架构。本文深度解析 CollectionListSetQueueMap 等核心接口与常用实现类(如 ArrayListHashMap),并提供选型指南、迭代遍历方案及并发集合补充,帮助开发者构建高效、可维护的 Java 应用程序。

集合框架概述

Java 集合框架提供了一套统一的架构,用于表示和操作各种类型的集合(如列表、集合、映射等)。它不仅大幅提升了编程效率,还增强了代码的可重用性与可维护性。

集合框架主要由以下核心接口组成:

  • Collection 接口:所有单列集合类型的根接口,定义了添加、删除、判断元素是否存在等基本操作。
  • List 接口:继承自 Collection,代表一个有序且允许重复的元素集合,支持通过索引精确访问。
  • Set 接口:继承自 Collection,代表一个不允许包含重复元素的集合,不保证元素顺序(具体取决于实现类)。
  • Queue 接口:继承自 Collection,代表一个队列,通常按照先进先出 (FIFO) 的原则存储和访问元素。
  • Map 接口独立于 Collection 体系,代表一个键值对 (Key-Value) 的集合,每个键映射到一个值,且键不允许重复。

除了核心接口,集合框架还提供了一系列实现类,如 ArrayListLinkedListHashSetTreeSetHashMapTreeMap 等。

集合框架体系图示

常用集合接口与实现类详解

List 接口:有序且可重复的集合

List 接口提供了基于索引的精确控制,常用方法包括:

  • add(E e) / add(int index, E e):在末尾或指定位置添加元素。
  • get(int index) / set(int index, E e):获取或替换指定位置的元素。
  • remove(int index) / remove(Object o):按索引或对象移除元素。
  • indexOf(Object o) / lastIndexOf(Object o):查找元素首次或末次出现的索引。
  • subList(int fromIndex, int toIndex):获取子列表视图。

示例代码:

import java.util.ArrayList; import java.util.List; public class ListExample { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("Apple"); list.add("Banana"); list.add("Orange"); list.add("Apple"); // 允许重复元素 System.out.println("List: " + list); System.out.println("Size: " + list.size()); System.out.println("Get element at index 1: " + list.get(1)); System.out.println("Index of Apple: " + list.indexOf("Apple")); System.out.println("Last index of Apple: " + list.lastIndexOf("Apple")); list.remove(2); System.out.println("List after removing index 2: " + list); List<String> subList = list.subList(0, 2); System.out.println("Sublist from 0 to 2: " + subList); } }

常用实现类对比:

实现类 底层数据结构 随机访问速度 插入/删除速度 适用场景
ArrayList 动态数组 快 (O(1)) 慢 (O(n)) 频繁读取、尾部追加
LinkedList 双向链表 慢 (O(n)) 快 (O(1)) 频繁在头部/中部插入或删除

Set 接口:唯一元素的集合

Set 接口主要用于数据去重,常用方法包括 add(E e)remove(Object o)contains(Object o) 等。若添加已存在的元素,add 方法将返回 false

示例代码:

import java.util.HashSet; import java.util.Set; public class SetExample { public static void main(String[] args) { Set<String> set = new HashSet<>(); set.add("Apple"); set.add("Banana"); set.add("Orange"); set.add("Apple"); // 重复元素,添加失败 System.out.println("Set: " + set); System.out.println("Contains Apple: " + set.contains("Apple")); set.remove("Banana"); System.out.println("Set after removing Banana: " + set); } }

常用实现类:

  • HashSet:基于哈希表实现,查找速度极快,但不保证顺序。
  • TreeSet:基于红黑树实现,元素自动排序(需实现 Comparable 接口或提供 Comparator)。
  • LinkedHashSet:继承自 HashSet,内部使用链表维护元素的插入顺序。

Queue 接口:先进先出的队列

Queue 接口用于处理具有特定顺序(通常是 FIFO)的元素。其方法分为两类:抛出异常的方法和返回特殊值的方法。

  • 抛出异常add(e)remove()element()
  • 返回特殊值offer(e)(满时返回 false)、poll()(空时返回 null)、peek()(空时返回 null)。

示例代码:

import java.util.LinkedList; import java.util.Queue; public class QueueExample { public static void main(String[] args) { Queue<String> queue = new LinkedList<>(); queue.offer("Apple"); queue.offer("Banana"); queue.offer("Orange"); System.out.println("Queue: " + queue); System.out.println("Peek: " + queue.peek()); System.out.println("Poll: " + queue.poll()); System.out.println("Queue after poll: " + queue); } }

常用实现类:

  • LinkedList:实现了 Queue 接口,可作为标准 FIFO 队列使用。
  • PriorityQueue:基于优先堆实现,元素按优先级(自然顺序或自定义比较器)出队,而非严格的 FIFO。

Map 接口:键值对映射集合

Map 不继承 Collection,用于存储 Key-Value 映射。Key 必须唯一,Value 可以重复。

常用方法:

  • put(K key, V value) / get(Object key):存入和获取键值对。
  • containsKey(Object key) / containsValue(Object value):判断是否包含特定键或值。
  • keySet() / values() / entrySet():获取键集合、值集合或键值对集合视图。

示例代码:

import java.util.HashMap; import java.util.Map; public class MapExample { public static void main(String[] args) { Map<String, Integer> map = new HashMap<>(); map.put("Apple", 1); map.put("Banana", 2); map.put("Orange", 3); map.put("Apple", 4); // 键重复,值被覆盖 System.out.println("Map: " + map); System.out.println("Get value for Apple: " + map.get("Apple")); System.out.println("Contains key Banana: " + map.containsKey("Banana")); map.remove("Banana"); System.out.println("Map after removing Banana: " + map); System.out.println("Entry Set: " + map.entrySet()); } }

常用实现类:

  • HashMap:基于哈希表(数组+链表+红黑树),允许 null 键和 null 值,无序。
  • TreeMap:基于红黑树,按键排序,不允许 null 键。
  • LinkedHashMap:维护插入顺序或访问顺序,常用于实现 LRU 缓存。

如何选择合适的集合类型?

在实际开发中,选择正确的集合类型对系统性能至关重要。以下是核心选型决策指南:

  1. 是否需要键值对映射?
    • \rightarrow 选择 Map。需要排序选 TreeMap,需要保持插入顺序选 LinkedHashMap,否则选 HashMap
    • \rightarrow 继续判断。
  2. 是否允许重复元素?
    • \rightarrow 选择 Set。需要排序选 TreeSet,需要保持插入顺序选 LinkedHashSet,否则选 HashSet
    • \rightarrow 继续判断。
  3. 是否需要特定的存取顺序(如 FIFO/LIFO)?
    • \rightarrow 选择 Queue/Deque。需要优先级选 PriorityQueue,否则选 LinkedListArrayDeque
    • \rightarrow 选择 List。频繁随机访问选 ArrayList,频繁头部/中部增删选 LinkedList

集合的遍历与迭代方式

Java 提供了多种遍历集合的方式,随着版本迭代,语法越来越简洁且功能更强大:

  1. Iterator 接口:最基础的迭代方式,支持在遍历时安全地删除元素(通过 iterator.remove())。
  2. 增强 for 循环 (foreach):语法简洁,底层基于 Iterator 实现,适用于只需读取元素的场景。
  3. Java 8 Stream API:支持函数式编程,适合复杂的过滤、映射和聚合操作。

综合示例代码:

import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class IteratorExample { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("Apple"); list.add("Banana"); list.add("Orange"); // 1. 使用 Iterator 迭代 (支持安全删除) System.out.println("Using Iterator:"); Iterator<String> iterator = list.iterator(); while (iterator.hasNext()) { String element = iterator.next(); if ("Banana".equals(element)) { iterator.remove(); // 安全删除 } else { System.out.println(element); } } // 2. 使用增强 for 循环 System.out.println("\nUsing enhanced for loop:"); for (String element : list) { System.out.println(element); } // 3. 使用 Java 8 Stream API 与 Lambda 表达式 System.out.println("\nUsing Stream API & forEach:"); list.stream() .filter(fruit -> !fruit.equals("Orange")) .forEach(System.out::println); } }

并发环境下的线程安全集合

标准的集合框架(如 ArrayListHashMap)在多线程环境下是不安全的。在并发编程中,应使用 java.util.concurrent 包下提供的线程安全集合:

  • ConcurrentHashMap:替代 HashtableCollections.synchronizedMap,采用 CAS + synchronized(JDK 1.8+)实现高并发读写,性能卓越。
  • CopyOnWriteArrayList:写时复制列表,适用于读多写少的并发场景。
  • ConcurrentLinkedQueue:基于 CAS 实现的无界非阻塞线程安全队列。
  • BlockingQueue (如 ArrayBlockingQueue):支持阻塞操作的队列,常用于生产者-消费者模型。

注意:尽量避免使用 VectorHashtable,这些遗留类虽然线程安全,但由于全表锁机制,性能较差,已被现代并发集合全面取代。

总结

Java 集合框架提供了一套强大、灵活且高度优化的数据结构工具库。深入理解 CollectionMap 体系的核心接口、底层数据结构差异以及各类实现类的性能特征,是编写高质量 Java 代码的基础。在实际应用中,开发者应根据数据规模、读写频率、是否需要排序以及并发环境等维度,精准选择最合适的集合类型,并结合 Stream API 与并发集合,构建出高效、健壮的企业级应用程序。


发布者: 作者: 转发
评论区 (0)
U