跳到主要内容

Java 集合框架

Java 集合框架(Collections Framework)是 Java 提供的用于存储和操作一组对象的数据结构。它提供了一套统一的标准接口和实现类,使开发者能够方便地对数据进行存储、检索和操作。

集合框架概述

Java 集合框架主要包括以下组成部分:

  • 接口:定义了不同类型集合的抽象数据类型
  • 实现类:提供了接口的具体实现
  • 算法:用于对集合进行排序、搜索等操作的静态方法

集合框架层次结构

Iterable
├── Collection
│ ├── List(有序、可重复)
│ │ ├── ArrayList
│ │ ├── LinkedList
│ │ └── Vector
│ ├── Set(无序、不可重复)
│ │ ├── HashSet
│ │ ├── LinkedHashSet
│ │ └── TreeSet
│ └── Queue(队列)
│ ├── LinkedList
│ └── PriorityQueue
└── Map(键值对)
├── HashMap
├── LinkedHashMap
├── TreeMap
└── Hashtable

List 接口

List 是有序集合(也称为序列),可以精确控制每个元素的位置,允许重复元素。

ArrayList

ArrayList 是最常用的 List 实现类,基于动态数组实现,适合随机访问。

import java.util.ArrayList;
import java.util.List;

List<String> list = new ArrayList<>();

// 添加元素
list.add("Apple");
list.add("Banana");
list.add("Orange");
list.add(1, "Grape"); // 在指定位置插入

// 访问元素
String first = list.get(0); // Apple
int size = list.size(); // 4

// 修改元素
list.set(0, "Pear"); // 将第一个元素改为Pear

// 删除元素
list.remove(0); // 删除第一个元素
list.remove("Banana"); // 删除指定元素

// 遍历方式
// 方式1:for循环
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}

// 方式2:增强for循环
for (String item : list) {
System.out.println(item);
}

// 方式3:迭代器
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
System.out.println(item);
}

// 方式4:forEach方法(Java 8+)
list.forEach(System.out::println);

LinkedList

LinkedList 基于双向链表实现,适合频繁的插入和删除操作。

import java.util.LinkedList;
import java.util.List;

LinkedList<String> linkedList = new LinkedList<>();

// 基本操作
linkedList.add("A");
linkedList.addFirst("First"); // 添加到头部
linkedList.addLast("Last"); // 添加到尾部
linkedList.removeFirst(); // 移除头部
linkedList.removeLast(); // 移除尾部

// 作为队列使用
linkedList.offer("B"); // 添加到尾部
String head = linkedList.poll(); // 移除头部

Vector

Vector 是线程安全的 ArrayList,所有方法都使用 synchronized 修饰。

import java.util.Vector;

Vector<String> vector = new Vector<>();
vector.add("A");
vector.addElement("B");

List 常用方法

方法说明
add(E e)添加元素到末尾
add(int index, E e)在指定位置添加元素
get(int index)获取指定位置的元素
set(int index, E e)修改指定位置的元素
remove(int index)删除指定位置的元素
remove(Object o)删除第一个匹配的元素
size()返回元素个数
contains(Object o)判断是否包含元素
indexOf(Object o)返回第一个匹配元素的索引
clear()清空所有元素
isEmpty()判断是否为空
subList(int from, int to)返回子列表

Set 接口

Set 是不允许重复元素的集合,主要用于去重。

HashSet

HashSet 基于哈希表实现,是 Set 接口最常用的实现类。

import java.util.HashSet;
import java.util.Set;

Set<String> set = new HashSet<>();

// 添加元素
set.add("Apple");
set.add("Banana");
set.add("Apple"); // 重复元素不会被添加,返回false

// 检查元素
boolean hasApple = set.contains("Apple"); // true
int size = set.size(); // 2

// 删除元素
set.remove("Apple");

// 遍历
for (String item : set) {
System.out.println(item);
}

LinkedHashSet

LinkedHashSet 继承自 HashSet,维护元素的插入顺序。

import java.util.LinkedHashSet;

LinkedHashSet<String> linkedSet = new LinkedHashSet<>();
linkedSet.add("First");
linkedSet.add("Second");
linkedSet.add("Third");
// 遍历顺序:First, Second, Third

TreeSet

TreeSet 基于红黑树实现,会自动对元素进行排序(自然顺序或自定义顺序)。

import java.util.TreeSet;
import java.util.Set;

Set<Integer> treeSet = new TreeSet<>();

treeSet.add(5);
treeSet.add(2);
treeSet.add(8);
treeSet.add(1);
// 遍历顺序:1, 2, 5, 8(自动升序)

// 使用自定义比较器
Set<String> treeSet2 = new TreeSet<>(Comparator.reverseOrder());
treeSet2.add("Apple");
treeSet2.add("Banana");
treeSet2.add("Orange");
// 遍历顺序:Orange, Banana, Apple(降序)

Set 常用方法

方法说明
add(E e)添加元素,如果已存在则返回false
remove(Object o)删除元素
contains(Object o)判断是否包含元素
size()返回元素个数
isEmpty()判断是否为空
clear()清空所有元素
iterator()返回迭代器

Queue 接口

Queue 是队列接口,用于存储待处理的元素。

PriorityQueue

PriorityQueue 是优先级队列,元素按自然顺序或自定义顺序排列。

import java.util.PriorityQueue;
import java.util.Queue;

Queue<Integer> pq = new PriorityQueue<>();

pq.add(5);
pq.add(2);
pq.add(8);
pq.add(1);

System.out.println(pq.poll()); // 1(最小元素)
System.out.println(pq.poll()); // 2
System.out.println(pq.poll()); // 5

Deque(双端队列)

Deque 继承自 Queue,支持在两端添加和删除元素。

import java.util.ArrayDeque;
import java.util.Deque;

Deque<String> deque = new ArrayDeque<>();

// 在两端添加
deque.addFirst("A");
deque.addLast("B");
deque.offerFirst("C");
deque.offerLast("D");

// 在两端删除
String first = deque.removeFirst();
String last = deque.removeLast();

Map 接口

Map 存储键值对(Key-Value),每个键最多映射到一个值。

HashMap

HashMap 是最常用的 Map 实现类,基于哈希表实现。

import java.util.HashMap;
import java.util.Map;

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

// 添加/修改
map.put("Apple", 1);
map.put("Banana", 2);
map.put("Orange", 3);
map.put("Apple", 5); // 会覆盖原来的值

// 访问
int value = map.get("Apple"); // 5
int defaultValue = map.getOrDefault("Grape", 0); // 0

// 检查
boolean hasKey = map.containsKey("Apple"); // true
boolean hasValue = map.containsValue(5); // true

// 删除
map.remove("Banana");

// 遍历方式
// 方式1:遍历键
for (String key : map.keySet()) {
System.out.println(key + ": " + map.get(key));
}

// 方式2:遍历键值对
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}

// 方式3:遍历值
for (Integer val : map.values()) {
System.out.println(val);
}

// 方式4:forEach(Java 8+)
map.forEach((key, value) -> System.out.println(key + ": " + value));

LinkedHashMap

LinkedHashMap 继承自 HashMap,维护键值对的插入顺序。

import java.util.LinkedHashMap;

LinkedHashMap<String, Integer> linkedMap = new LinkedHashMap<>();
linkedMap.put("A", 1);
linkedMap.put("B", 2);
linkedMap.put("C", 3);
// 遍历顺序:A, B, C

TreeMap

TreeMap 基于红黑树实现,会自动按键排序。

import java.util.TreeMap;
import java.util.Map;

Map<String, Integer> treeMap = new TreeMap<>();

treeMap.put("Banana", 2);
treeMap.put("Apple", 1);
treeMap.put("Orange", 3);
// 遍历顺序:Apple, Banana, Orange(按键自然顺序)

Hashtable

Hashtable 是线程安全的 Map 实现,但已被淘汰,推荐使用 ConcurrentHashMap。

import java.util.Hashtable;

Hashtable<String, Integer> hashtable = new Hashtable<>();
hashtable.put("A", 1);
// 不允许 null 键或 null 值

Map 常用方法

方法说明
put(K key, V value)添加键值对
get(Object key)获取值
getOrDefault(K key, V defaultValue)获取值,不存在返回默认值
remove(Object key)删除键值对
containsKey(Object key)判断是否包含键
containsValue(Object value)判断是否包含值
keySet()获取所有键的集合
values()获取所有值的集合
entrySet()获取所有键值对的集合
size()返回键值对数量
isEmpty()判断是否为空
clear()清空所有元素

迭代器

迭代器提供了一种统一的方式来遍历集合。

import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;

List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");

// 使用 Iterator
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
String item = iterator.next();
if ("B".equals(item)) {
iterator.remove(); // 安全删除
}
}

// 使用 ListIterator(双向遍历)
ListIterator<String> listIterator = list.listIterator();
while (listIterator.hasNext()) {
System.out.println(listIterator.next());
}
while (listIterator.hasPrevious()) {
System.out.println(listIterator.previous());
}

Collections 工具类

Collections 提供了一些静态方法来操作集合。

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

// 排序
List<Integer> list = new ArrayList<>(Arrays.asList(3, 1, 2));
Collections.sort(list); // [1, 2, 3]

// 反转
Collections.reverse(list); // [3, 2, 1]

// 查找(需先排序)
int index = Collections.binarySearch(list, 2);

// 填充
Collections.fill(list, 0); // [0, 0, 0]

// 交换
Collections.swap(list, 0, 2);

// 最大/最小
int max = Collections.max(list);
int min = Collections.min(list);

// 不可变集合
List<String> immutableList = Collections.unmodifiableList(list);

// 同步集合(线程安全)
List<String> synchronizedList = Collections.synchronizedList(list);

Stream API(Java 8+)

Java 8 引入了 Stream API,可以对集合进行函数式操作。

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

// 过滤
List<Integer> even = numbers.stream()
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());

// 映射
List<Integer> squares = numbers.stream()
.map(n -> n * n)
.collect(Collectors.toList());

// 排序
List<Integer> sorted = numbers.stream()
.sorted()
.collect(Collectors.toList());

// 聚合
int sum = numbers.stream()
.mapToInt(Integer::intValue)
.sum();

double avg = numbers.stream()
.mapToInt(Integer::intValue)
.average()
.orElse(0);

// 分组
Map<String, List<Integer>> grouped = numbers.stream()
.collect(Collectors.groupingBy(n -> n % 2 == 0 ? "偶数" : "奇数"));

// 查找
Integer first = numbers.stream()
.findFirst()
.orElse(0);

boolean anyMatch = numbers.stream()
.anyMatch(n -> n > 3);

小结

本章我们详细学习了 Java 集合框架的核心内容:

  1. List 接口:ArrayList、LinkedList、Vector 的使用
  2. Set 接口:HashSet、LinkedHashSet、TreeSet 的特点和选择
  3. Queue 接口:PriorityQueue、ArrayDeque 的使用
  4. Map 接口:HashMap、LinkedHashMap、TreeMap 的使用
  5. 迭代器:遍历和操作集合的统一方式
  6. Collections 工具类:集合操作的辅助方法
  7. Stream API:函数式编程风格的数据处理

选择合适的集合类型:

  • 需要有序且可重复 → List(ArrayList 或 LinkedList)
  • 需要去重 → Set(HashSet、TreeSet、LinkedHashSet)
  • 需要键值对 → Map(HashMap、TreeMap、LinkedHashMap)
  • 需要按优先级处理 → PriorityQueue
  • 需要线程安全 → ConcurrentHashMap、ConcurrentLinkedQueue