集合框架
集合体系结构
Collection(接口)
├── List(接口)
│ ├── ArrayList
│ ├── LinkedList
│ └── Vector
├── Set(接口)
│ ├── HashSet
│ ├── LinkedHashSet
│ └── TreeSet
└── Queue(接口)
├── LinkedList
├── ArrayDeque
└── PriorityQueue
Map(接口)
├── HashMap
├── LinkedHashMap
├── TreeMap
└── HashtableList接口
ArrayList
基于动态数组实现,查询快,增删慢。
java
import java.util.ArrayList;
import java.util.List;
public class ArrayListDemo {
public static void main(String[] args) {
// 创建ArrayList
List<String> list = new ArrayList<>();
// 添加元素
list.add("张三");
list.add("李四");
list.add("王五");
list.add(1, "赵六"); // 指定位置插入
// 获取元素
System.out.println(list.get(0)); // 张三
// 修改元素
list.set(0, "张三丰");
// 删除元素
list.remove(1); // 按索引删除
list.remove("王五"); // 按值删除
// 查询
System.out.println(list.contains("李四")); // true
System.out.println(list.indexOf("李四")); // 1
System.out.println(list.size()); // 2
// 遍历
for (String name : list) {
System.out.println(name);
}
// 清空
list.clear();
System.out.println(list.isEmpty()); // true
}
}LinkedList
基于双向链表实现,增删快,查询慢。
java
import java.util.LinkedList;
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<>();
// 添加元素
list.add("中间");
list.addFirst("头部");
list.addLast("尾部");
// 获取元素
System.out.println(list.getFirst()); // 头部
System.out.println(list.getLast()); // 尾部
// 删除元素
list.removeFirst();
list.removeLast();
// 栈操作
list.push("A"); // 压栈
list.push("B");
System.out.println(list.pop()); // B(出栈)
// 队列操作
list.offer("X"); // 入队
list.offer("Y");
System.out.println(list.poll()); // X(出队)
}
}ArrayList vs LinkedList
| 特性 | ArrayList | LinkedList |
|---|---|---|
| 底层结构 | 动态数组 | 双向链表 |
| 随机访问 | O(1) 快 | O(n) 慢 |
| 插入删除 | O(n) 慢 | O(1) 快(已知位置) |
| 内存占用 | 较小 | 较大 |
| 适用场景 | 查询多 | 增删多 |
Set接口
HashSet
基于哈希表实现,元素无序,不允许重复。
java
import java.util.HashSet;
import java.util.Set;
public class HashSetDemo {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
// 添加元素
set.add("张三");
set.add("李四");
set.add("王五");
set.add("张三"); // 重复元素不会被添加
System.out.println(set.size()); // 3
// 判断是否存在
System.out.println(set.contains("张三")); // true
// 删除元素
set.remove("李四");
// 遍历(无序)
for (String name : set) {
System.out.println(name);
}
}
}LinkedHashSet
保持插入顺序。
java
import java.util.LinkedHashSet;
public class LinkedHashSetDemo {
public static void main(String[] args) {
LinkedHashSet<String> set = new LinkedHashSet<>();
set.add("C");
set.add("A");
set.add("B");
// 按插入顺序输出
for (String s : set) {
System.out.println(s); // C, A, B
}
}
}TreeSet
基于红黑树实现,元素有序。
java
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<Integer> set = new TreeSet<>();
set.add(5);
set.add(1);
set.add(3);
set.add(2);
// 自动排序
System.out.println(set); // [1, 2, 3, 5]
// 导航方法
System.out.println(set.first()); // 1
System.out.println(set.last()); // 5
System.out.println(set.lower(3)); // 2(小于3的最大值)
System.out.println(set.higher(3)); // 5(大于3的最小值)
// 范围查询
System.out.println(set.subSet(2, 5)); // [2, 3]
}
}Map接口
HashMap
基于哈希表实现,键值对存储,键不允许重复。
java
import java.util.HashMap;
import java.util.Map;
public class HashMapDemo {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
// 添加键值对
map.put("张三", 25);
map.put("李四", 30);
map.put("王五", 28);
// 获取值
System.out.println(map.get("张三")); // 25
// 判断键是否存在
System.out.println(map.containsKey("张三")); // true
System.out.println(map.containsValue(30)); // true
// 修改值
map.put("张三", 26);
// 如果键不存在才添加
map.putIfAbsent("赵六", 35);
// 删除
map.remove("李四");
// 遍历
// 遍历键
for (String key : map.keySet()) {
System.out.println(key + ": " + map.get(key));
}
// 遍历值
for (Integer value : map.values()) {
System.out.println(value);
}
// 遍历键值对
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
// Java 8+ forEach
map.forEach((k, v) -> System.out.println(k + ": " + v));
}
}LinkedHashMap
保持插入顺序或访问顺序。
java
import java.util.LinkedHashMap;
public class LinkedHashMapDemo {
public static void main(String[] args) {
// 按插入顺序
LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
map.put("C", 3);
map.put("A", 1);
map.put("B", 2);
map.forEach((k, v) -> System.out.println(k)); // C, A, B
// 按访问顺序(LRU缓存)
LinkedHashMap<String, Integer> lru = new LinkedHashMap<>(16, 0.75f, true);
lru.put("A", 1);
lru.put("B", 2);
lru.put("C", 3);
lru.get("A"); // 访问A
lru.forEach((k, v) -> System.out.println(k)); // B, C, A
}
}TreeMap
按键排序。
java
import java.util.TreeMap;
public class TreeMapDemo {
public static void main(String[] args) {
TreeMap<String, Integer> map = new TreeMap<>();
map.put("C", 3);
map.put("A", 1);
map.put("B", 2);
// 按键排序
System.out.println(map); // {A=1, B=2, C=3}
// 导航方法
System.out.println(map.firstKey()); // A
System.out.println(map.lastKey()); // C
System.out.println(map.lowerKey("B")); // A
System.out.println(map.higherKey("B"));// C
}
}Queue接口
PriorityQueue
优先级队列,按优先级出队。
java
import java.util.PriorityQueue;
public class PriorityQueueDemo {
public static void main(String[] args) {
PriorityQueue<Integer> queue = new PriorityQueue<>();
queue.offer(5);
queue.offer(1);
queue.offer(3);
// 按自然顺序出队
while (!queue.isEmpty()) {
System.out.println(queue.poll()); // 1, 3, 5
}
}
}ArrayDeque
双端队列,可作为栈或队列使用。
java
import java.util.ArrayDeque;
public class ArrayDequeDemo {
public static void main(String[] args) {
ArrayDeque<Integer> deque = new ArrayDeque<>();
// 作为栈使用
deque.push(1);
deque.push(2);
deque.push(3);
System.out.println(deque.pop()); // 3
// 作为队列使用
deque.offer(4);
deque.offer(5);
System.out.println(deque.poll()); // 1
}
}Collections工具类
java
import java.util.*;
public class CollectionsDemo {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>(Arrays.asList(3, 1, 4, 1, 5, 9));
// 排序
Collections.sort(list);
System.out.println(list); // [1, 1, 3, 4, 5, 9]
// 反转
Collections.reverse(list);
System.out.println(list); // [9, 5, 4, 3, 1, 1]
// 打乱
Collections.shuffle(list);
// 查找
System.out.println(Collections.max(list)); // 9
System.out.println(Collections.min(list)); // 1
// 二分查找(需要先排序)
Collections.sort(list);
System.out.println(Collections.binarySearch(list, 4)); // 4
// 填充
Collections.fill(list, 0);
System.out.println(list); // [0, 0, 0, 0, 0, 0]
// 复制
List<Integer> dest = new ArrayList<>(Collections.nCopies(6, 0));
Collections.copy(dest, Arrays.asList(1, 2, 3));
// 不可变集合
List<String> immutable = Collections.unmodifiableList(
Arrays.asList("A", "B", "C")
);
// immutable.add("D"); // 抛出异常
}
}集合选择指南
| 需求 | 推荐集合 |
|---|---|
| 频繁查询 | ArrayList |
| 频繁增删 | LinkedList |
| 去重、快速查找 | HashSet |
| 去重、保持顺序 | LinkedHashSet |
| 去重、排序 | TreeSet |
| 键值对存储 | HashMap |
| 键值对、保持顺序 | LinkedHashMap |
| 键值对、按键排序 | TreeMap |
| 优先级处理 | PriorityQueue |
| 栈/队列 | ArrayDeque |