Skip to content

Java 集合框架完全解析

Collection、List、Set、Map、Queue 完整对比与使用场景


集合框架结构

Iterable
    └── Collection
            ├── List(有序、可重复)
            │       ├── ArrayList
            │       ├── LinkedList
            │       └── Vector → Stack

            ├── Set(无序、不可重复)
            │       ├── HashSet
            │       ├── LinkedHashSet
            │       └── TreeSet

            └── Queue(队列)
                    ├── Deque
                    │       ├── ArrayDeque
                    │       └── LinkedList

                    ├── BlockingQueue
                    │       ├── ArrayBlockingQueue
                    │       └── LinkedBlockingQueue

                    └── PriorityQueue

└── Map(键值对)
        ├── HashMap
        ├── LinkedHashMap
        ├── TreeMap
        ├── Hashtable
        └── ConcurrentHashMap

Collection 接口

核心方法

java
public interface Collection<E> extends Iterable<E> {
    // 基本操作
    int size();
    boolean isEmpty();
    boolean contains(Object o);
    boolean add(E e);
    boolean remove(Object o);
    
    // 批量操作
    boolean addAll(Collection<? extends E> c);
    boolean removeAll(Collection<?> c);
    boolean retainAll(Collection<?> c);
    void clear();
    
    // 数组转换
    Object[] toArray();
    <T> T[] toArray(T[] a);
    
    // 遍历
    Iterator<E> iterator();
    void forEach(Consumer<? super E> action);
    
    // 批量操作(Java 8+)
    boolean removeIf(Predicate<? super E> filter);
    Stream<E> stream();
    Stream<E> parallelStream();
}

List 接口

特性

特性说明
有序元素按插入顺序存储
可重复允许存入相同元素
有索引通过下标访问(get(index))
线程不安全Collections.synchronizedList() 或 CopyOnWriteArrayList

ArrayList

原理:Object[] 数组,默认容量 10,扩容 1.5 倍

java
// 初始化
List<String> list = new ArrayList<>();
List<String> list = new ArrayList<>(20);  // 指定初始容量

// 添加元素
list.add("A");
list.add(0, "B");  // 插入到指定位置

// 访问
String first = list.get(0);

// 修改
list.set(0, "C");

// 删除
list.remove(0);      // 按索引删除
list.remove("A");    // 按对象删除

// 遍历
for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}

for (String s : list) {
    System.out.println(s);
}

list.forEach(System.out::println);

Iterator<String> it = list.iterator();
while (it.hasNext()) {
    String s = it.next();
    if (s.equals("A")) {
        it.remove();
    }
}

特点

操作复杂度
随机访问O(1)
尾部插入O(1) 均摊
中间插入/删除O(n)
查找O(n)

适用场景:需要随机访问、尾部操作多、中间操作少


LinkedList

原理:双向链表,头尾操作 O(1)

java
LinkedList<String> list = new LinkedList<>();

// 队列操作
list.offer("A");         // 队尾插入
list.poll();             // 队首取出
list.peek();             // 查看队首

// 栈操作
list.push("A");          // 压栈
list.pop();              // 弹栈

// 双端队列
list.addFirst("A");
list.addLast("B");
list.removeFirst();
list.removeLast();

特点

操作复杂度
头部插入/删除O(1)
尾部插入/删除O(1)
随机访问O(n)
中间插入/删除O(n)

适用场景:栈/队列实现、头尾操作频繁、遍历多随机访问少


Vector / Stack

java
// Vector(同步,线程安全)
Vector<String> vector = new Vector<>();
vector.add("A");

// Stack(继承 Vector,FILO)
Stack<String> stack = new Stack<>();
stack.push("A");
stack.push("B");
stack.pop();   // B
stack.peek();  // A
stack.empty();

注意:推荐用 ArrayDeque 替代 Stack,性能更好


List 对比

特性ArrayListLinkedListVector
底层结构数组双向链表数组
线程安全
扩容机制1.5 倍无需扩容2 倍
随机访问O(1)O(n)O(1)
头插入O(n)O(1)O(n)
尾插入O(1) 均摊O(1)O(1)
内存占用高(节点)
推荐场景通用场景栈/队列需线程安全

Set 接口

特性

特性说明
无序不保证迭代顺序(HashSet/TreeSet 可控)
不可重复equals() 判断重复
支持泛型只存一个元素
线程不安全Collections.synchronizedSet() 或 CopyOnWriteArraySet

HashSet

原理:HashMap 存储元素,key 存元素,value 存 PRESENT

java
Set<String> set = new HashSet<>();
set.add("A");
set.add("B");
set.add("A");  // 添加失败,不重复

boolean contains = set.contains("A");
set.remove("A");
set.size();
set.isEmpty();
set.clear();

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

特点

  • 无序(哈希码决定顺序)
  • 允许 null 元素
  • 查找/添加:O(1) 均摊
  • 需正确实现 hashCode() 和 equals()

LinkedHashSet

原理:HashMap + 双向链表,保持插入顺序

java
Set<String> set = new LinkedHashSet<>();
set.add("C");
set.add("A");
set.add("B");
// 迭代顺序:C -> A -> B(插入顺序)

适用场景:需要保持元素插入顺序


TreeSet

原理:红黑树,按自然顺序或Comparator排序

java
// 自然顺序
Set<Integer> set = new TreeSet<>();
set.add(3);
set.add(1);
set.add(2);
// 迭代顺序:1 -> 2 -> 3

// 自定义顺序
Set<String> set = new TreeSet<>(Comparator.reverseOrder());
set.add("apple");
set.add("banana");
set.add("cherry");
// 迭代顺序:cherry -> banana -> apple

// 自定义比较器
Set<User> set = new TreeSet<>(Comparator.comparing(User::getName));

特点

操作复杂度
添加O(log n)
删除O(log n)
查找O(log n)
范围查找O(log n + k)

适用场景:需要排序、有序遍历、范围查询


Set 对比

特性HashSetLinkedHashSetTreeSet
底层结构HashMapLinkedHashMap红黑树
迭代顺序无序插入顺序排序顺序
null 支持
线程安全
查找/添加O(1)O(1)O(log n)
排序
适用场景最常用、去重保持顺序需要排序

Map 接口

核心方法

java
public interface Map<K, V> {
    // 基本操作
    V put(K key, V value);
    V get(Object key);
    V remove(Object key);
    boolean containsKey(Object key);
    boolean containsValue(Object value);
    int size();
    boolean isEmpty();
    void clear();
    
    // 批量操作
    void putAll(Map<? extends K, ? extends V> m);
    
    // 视图
    Set<K> keySet();
    Collection<V> values();
    Set<Map.Entry<K, V>> entrySet();
    
    // Entry
    interface Entry<K, V> {
        K getKey();
        V getValue();
        V setValue(V value);
    }
    
    // Java 8+
    V getOrDefault(Object key, V defaultValue);
    V putIfAbsent(K key, V value);
    boolean remove(Object key, Object value);
    boolean replace(K key, V oldValue, V newValue);
    V replace(K key, V value);
    void replaceAll(BiFunction<? super K, ? super V, ? extends V> function);
    void forEach(BiConsumer<? super K, ? super V> action);
    merge(K key, V value, BiFunction<V, V, V> remappingFunction);
    compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction);
    computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction);
    computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction);
}

HashMap

原理:数组 + 链表/红黑树( JDK 1.8+ ),链表超过 8 转为红黑树

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

// 添加
map.put("A", 1);
map.put("B", 2);
map.put("C", 3);

// 获取
Integer value = map.get("A");
Integer defaultVal = map.getOrDefault("D", 0);  // 0

// 修改
map.put("A", 10);          // 覆盖
map.replace("B", 20);    // 返回旧值

// 删除
map.remove("A");
map.remove("B", 2);        // key 和 value 都匹配才删除

// 判断
boolean hasA = map.containsKey("A");
boolean hasOne = map.containsValue(1);

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

for (String key : map.keySet()) {
    System.out.println(key);
}

for (Integer value : map.values()) {
    System.out.println(value);
}

map.forEach((k, v) -> System.out.println(k + " = " + v));

特点

操作复杂度
get/putO(1) 均摊
最坏情况O(n)(大量哈希冲突)
容量2^n,自动扩容
初始容量16,负载因子 0.75

LinkedHashMap

原理:HashMap + 双向链表,保持访问/插入顺序

java
Map<String, Integer> map = new LinkedHashMap<>();
map.put("C", 3);
map.put("A", 1);
map.put("B", 2);
// 迭代顺序:C -> A -> B

// 访问顺序(LRU 缓存)
Map<String, Integer> lru = new LinkedHashMap<>(16, 0.75f, true);
lru.put("A", 1);
lru.put("B", 2);
lru.get("A");  // 访问后顺序变为:B -> A

TreeMap

原理:红黑树,按 key 排序

java
Map<String, Integer> map = new TreeMap<>();
map.put("c", 3);
map.put("a", 1);
map.put("b", 2);
// 迭代顺序:a -> b -> c(字典序)

// 自定义排序
Map<String, Integer> map = new TreeMap<>(Comparator.reverseOrder());

// 导航方法
map.ceilingKey("B");   // >= "B" 的最小 key
map.floorKey("B");     // <= "B" 的最大 key
map.higherKey("B");    // > "B" 的最小 key
map.lowerKey("B");     // < "B" 的最大 key
map.firstEntry();      // 最小 entry
map.lastEntry();       // 最大 entry

Hashtable

原理:早期实现,线程安全( synchronized ),不允许 null

java
Map<String, Integer> map = new Hashtable<>();
map.put("A", 1);
map.get("A");
map.remove("A");

注意:已过时,推荐用 ConcurrentHashMap


Map 对比

特性HashMapLinkedHashMapTreeMapHashtable
底层结构数组+链表/红黑树HashMap+链表红黑树数组+链表
迭代顺序无序插入/访问顺序排序顺序无序
null key
null value
线程安全
查找/添加O(1)O(1)O(log n)O(1)
排序
适用场景最常用保持顺序需要排序需线程安全

Queue 接口

核心方法

java
public interface Queue<E> extends Collection<E> {
    // 添加(队列满时抛异常)
    void add(E e);
    
    // 添加(队列满时返回 false)
    boolean offer(E e);
    
    // 移除(队列空时抛异常)
    E remove();
    
    // 移除(队列空时返回 null)
    E poll();
    
    // 查看(队列空时抛异常)
    E element();
    
    // 查看(队列空时返回 null)
    E peek();
}

Deque 接口

java
public interface Deque<E> extends Queue<E> {
    // 两端操作
    void addFirst(E e);
    void addLast(E e);
    boolean offerFirst(E e);
    boolean offerLast(E e);
    
    E removeFirst();
    E removeLast();
    E pollFirst();
    E pollLast();
    
    E getFirst();
    E getLast();
    E peekFirst();
    E peekLast();
    
    // 栈操作
    void push(E e);   // = addFirst
    E pop();          // = removeFirst
}

实现类对比

实现类底层null线程安全特点
ArrayDeque数组栈/队列首选,性能好
LinkedList链表可做 List/Deque
PriorityQueue按优先级排序
ArrayBlockingQueue数组有界队列
LinkedBlockingQueue链表可选有界/无界

ArrayDeque

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

// 队列操作
deque.offer("A");     // 队尾
deque.offer("B");
deque.poll();         // 队首:A

// 栈操作
deque.push("X");      // 栈顶
deque.push("Y");
deque.pop();          // Y

// 双端操作
deque.addFirst("F");
deque.addLast("L");
deque.removeFirst();
deque.removeLast();

PriorityQueue

java
// 最小堆(默认)
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
minHeap.add(5);
minHeap.add(2);
minHeap.add(8);
minHeap.poll();  // 2

// 最大堆
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Comparator.reverseOrder());

// 自定义比较器
PriorityQueue<User> users = new PriorityQueue<>(
    Comparator.comparingInt(User::getAge).reversed()
);

线程安全集合

对比

线程安全实现适用场景
Collections.synchronizedList/Set/Map简单场景,性能要求不高
CopyOnWriteArrayList读多写少
CopyOnWriteArraySet读多写少,元素少
ConcurrentHashMap高并发读写的 Map
ConcurrentLinkedQueue高并发无界队列
BlockingQueue生产者-消费者模式
ConcurrentSkipListMap/Set需要排序的高并发

ConcurrentHashMap

java
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();

// 基本操作
map.put("A", 1);
map.get("A");

// 原子操作
map.putIfAbsent("A", 1);     // key 不存在才插入
map.remove("A", 1);          // key-value 都匹配才删除
map.replace("A", 1, 10);     // key-oldValue 匹配才替换

// 批量操作
map.putAll(anotherMap);

// 遍历(弱一致性)
map.forEach((k, v) -> {});
map.entrySet().forEach(e -> {});

// 计数
map.mappingCount();  // 返回 long

// 搜索
map.search(1, (k, v) -> v > 10 ? k : null);

BlockingQueue

java
BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);

// 生产者
queue.put("A");      // 队列满则阻塞
queue.offer("A", 1, TimeUnit.SECONDS);  // 超时放弃

// 消费者
String item = queue.take();  // 队列空则阻塞
String item = queue.poll(1, TimeUnit.SECONDS);  // 超时返回 null

实现类

特点
ArrayBlockingQueue有界,数组
LinkedBlockingQueue可选有界/无界,链表
SynchronousQueue不存储元素,必须同步交接
PriorityBlockingQueue无界,按优先级
DelayQueue无界,延迟元素

集合工具类

Collections

java
// 排序
List<Integer> list = new ArrayList<>();
Collections.sort(list);
Collections.sort(list, Comparator.reverseOrder());

// 逆序
Collections.reverse(list);

// 混排(洗牌)
Collections.shuffle(list);

// 查找
int index = Collections.binarySearch(sortedList, target);

// 极值
Collections.max(collection);
Collections.min(collection);

// 同步控制
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
Set<String> syncSet = Collections.synchronizedSet(new HashSet<>());
Map<String, Integer> syncMap = Collections.synchronizedMap(new HashMap<>());

// 不可变集合
List<String> immutable = Collections.unmodifiableList(list);
Set<String> immutableSet = Collections.unmodifiableSet(set);
Map<String, Integer> immutableMap = Collections.unmodifiableMap(map);

// 单一元素集合
Set<String> singleton = Collections.singleton("only");
List<String> singletonList = Collections.singletonList("only");
Map<String, Integer> singletonMap = Collections.singletonMap("key", 1);

// 空集合
Collections.emptyList();
Collections.emptySet();
Collections.emptyMap();

Arrays

java
// 数组转 List
String[] arr = {"A", "B", "C"};
List<String> list = Arrays.asList(arr);
List<String> list = Arrays.asList("A", "B", "C");

// List 转数组
String[] arr = list.toArray(new String[0]);
String[] arr = list.toArray(String[]::new);

// 数组排序
int[] nums = {3, 1, 2};
Arrays.sort(nums);
Arrays.sort(nums, Comparator.reverseOrder());

// 数组填充
Arrays.fill(arr, 0);

// 数组二分查找
int index = Arrays.binarySearch(sortedArr, target);

// 数组比较
boolean equal = Arrays.equals(arr1, arr2);

// 数组转字符串
String str = Arrays.toString(arr);

// 创建空数组
String[] empty = Arrays.emptyArray();

// 构造数组的流
Arrays.stream(nums).sum();

最佳实践

选择合适的集合

场景推荐
需要快速查找HashMap / HashSet
需要保持顺序LinkedHashMap / LinkedHashSet
需要按键排序TreeMap / TreeSet
需要频繁头尾操作ArrayDeque / LinkedList
需要按优先级PriorityQueue
高并发读写ConcurrentHashMap
读多写少CopyOnWriteArrayList

性能优化

java
// 指定初始容量,避免扩容
new ArrayList<>(expectedSize);
new HashMap<>(expectedSize);

// 使用接口编程
List<String> list = new ArrayList<>();  // 面向接口
Set<String> set = new HashSet<>();

// 选择合适的实现
// ArrayList vs LinkedList
// 尾插多用 ArrayList
// 头插多用 LinkedList

// 避免使用包装类型做 key
// 用 String / Integer 代替自定义对象

常见错误

java
// ❌ 错误:数组转型
List<Object> list = new ArrayList<String>();  // 编译错误

// ❌ 错误:在遍历中删除
for (String s : list) {
    list.remove(s);  // ConcurrentModificationException
}

// ✅ 正确:迭代器删除
Iterator<String> it = list.iterator();
while (it.hasNext()) {
    if (condition) {
        it.remove();
    }
}

// ✅ 正确:removeIf
list.removeIf(s -> condition);

// ❌ 错误:可变对象做 key
Map<List<String>, Integer> map;  // 不推荐,list 内容变化后哈希失效

// ✅ 正确:使用不可变对象
Map<String, Integer> map;

相关页面

  • **Java\Java_base\Java基础-完全指南** - 返回总览
  • **Java\Java_advanced\Stream流收集数据与Lambda详解** - Stream API
  • **Java\Java_advanced\Java多线程编程** - 并发集合

#标签 #java #集合 #collection #list #set #map #queue #数据结构

Knowledge4J — Java 知识库