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 集合框架的核心内容:
- List 接口:ArrayList、LinkedList、Vector 的使用
- Set 接口:HashSet、LinkedHashSet、TreeSet 的特点和选择
- Queue 接口:PriorityQueue、ArrayDeque 的使用
- Map 接口:HashMap、LinkedHashMap、TreeMap 的使用
- 迭代器:遍历和操作集合的统一方式
- Collections 工具类:集合操作的辅助方法
- Stream API:函数式编程风格的数据处理
选择合适的集合类型:
- 需要有序且可重复 → List(ArrayList 或 LinkedList)
- 需要去重 → Set(HashSet、TreeSet、LinkedHashSet)
- 需要键值对 → Map(HashMap、TreeMap、LinkedHashMap)
- 需要按优先级处理 → PriorityQueue
- 需要线程安全 → ConcurrentHashMap、ConcurrentLinkedQueue