深入理解 Java 集合框架 - 详解

深入理解 Java 集合框架 - 详解

目录

1. 集合框架概述

1.1 什么是集合框架?

1.2 集合框架的体系结构

2. Collection 接口及其实现

2.1 List 接口

ArrayList

LinkedList

Vector vs ArrayList

2.2 Set 接口

HashSet

LinkedHashSet

TreeSet

2.3 Queue 接口

PriorityQueue

ArrayDeque

3. Map 接口及其实现

3.1 HashMap

3.2 LinkedHashMap

3.3 TreeMap

3.4 Hashtable vs HashMap

4. 集合的线程安全版本

4.1 同步包装器

4.2 Concurrent 集合(Java 5+)

5. 集合的性能比较

5.1 List 性能比较

5.2 Set 性能比较

5.3 Map 性能比较

6. 集合的最佳实践

6.1 选择合适的集合

6.2 初始化容量

6.3 使用增强for循环和迭代器

6.4 Java 8+ 新特性

7. 常见面试问题

7.1 HashMap 的工作原理

7.2 ArrayList 和 LinkedList 的区别

7.3 ConcurrentHashMap 的实现原理

8. 总结

关键要点:

选择指南:

Java 集合框架(Java Collections Framework)是 Java 语言中最重要的组成部分之一。

1. 集合框架概述1.1 什么是集合框架?Java 集合框架是一组用于表示和操作集合的统一架构,包含:

接口:定义集合的基本操作实现:接口的具体实现类算法:对集合进行操作的方法(如排序、搜索)1.2 集合框架的体系结构

Collection

├── List (有序、可重复)

│ ├── ArrayList

│ ├── LinkedList

│ └── Vector

│ └── Stack

├── Set (无序、不可重复)

│ ├── HashSet

│ │ └── LinkedHashSet

│ ├── TreeSet

│ └── EnumSet

└── Queue (队列)

├── PriorityQueue

├── ArrayDeque

└── LinkedList

Map (键值对)

├── HashMap

│ └── LinkedHashMap

├── TreeMap

├── Hashtable

│ └── Properties

└── EnumMap

2. Collection 接口及其实现2.1 List 接口ArrayList

// ArrayList 示例

List arrayList = new ArrayList<>();

arrayList.add("Java");

arrayList.add("Python");

arrayList.add("C++");

// 随机访问高效

System.out.println(arrayList.get(1)); // 输出: Python

// 遍历

for (String language : arrayList) {

System.out.println(language);

}

// 特点:基于数组,随机访问快,插入删除慢(需要移动元素)

LinkedList

// LinkedList 示例

List linkedList = new LinkedList<>();

linkedList.add("Apple");

linkedList.add("Banana");

linkedList.addFirst("Orange"); // 在开头添加

// 插入删除高效

linkedList.remove(1); // 删除第二个元素

// 特点:基于双向链表,插入删除快,随机访问慢

Vector vs ArrayList

// Vector 是线程安全的,但性能较差

Vector vector = new Vector<>();

vector.add("item1");

vector.add("item2");

// ArrayList 非线程安全,但性能更好

List arrayList = new ArrayList<>();

2.2 Set 接口HashSet

// HashSet 示例

Set hashSet = new HashSet<>();

hashSet.add("北京");

hashSet.add("上海");

hashSet.add("北京"); // 重复元素不会被添加

System.out.println(hashSet); // 输出: [北京, 上海]

System.out.println(hashSet.contains("上海")); // true

// 特点:基于HashMap,无序,查询速度快

LinkedHashSet

// LinkedHashSet 保持插入顺序

Set linkedHashSet = new LinkedHashSet<>();

linkedHashSet.add("第一");

linkedHashSet.add("第二");

linkedHashSet.add("第三");

System.out.println(linkedHashSet); // 输出: [第一, 第二, 第三]

TreeSet

// TreeSet 自然排序

Set treeSet = new TreeSet<>();

treeSet.add("orange");

treeSet.add("apple");

treeSet.add("banana");

System.out.println(treeSet); // 输出: [apple, banana, orange]

// 自定义排序

Set customSet = new TreeSet<>(Comparator.reverseOrder());

customSet.add(5);

customSet.add(1);

customSet.add(10);

System.out.println(customSet); // 输出: [10, 5, 1]

2.3 Queue 接口PriorityQueue

// 优先级队列

Queue priorityQueue = new PriorityQueue<>();

priorityQueue.offer(5);

priorityQueue.offer(1);

priorityQueue.offer(10);

while (!priorityQueue.isEmpty()) {

System.out.println(priorityQueue.poll()); // 输出: 1, 5, 10

}

ArrayDeque

// 双端队列

Deque deque = new ArrayDeque<>();

deque.offerFirst("first");

deque.offerLast("last");

deque.offer("middle");

System.out.println(deque.pollFirst()); // 输出: first

System.out.println(deque.pollLast()); // 输出: last

3. Map 接口及其实现3.1 HashMap

// HashMap 示例

Map hashMap = new HashMap<>();

hashMap.put("Alice", 25);

hashMap.put("Bob", 30);

hashMap.put("Charlie", 28);

// 获取值

System.out.println(hashMap.get("Alice")); // 输出: 25

// 遍历

for (Map.Entry entry : hashMap.entrySet()) {

System.out.println(entry.getKey() + ": " + entry.getValue());

}

// Java 8+ 方法

hashMap.forEach((k, v) -> System.out.println(k + ": " + v));

3.2 LinkedHashMap

// 保持插入顺序的Map

Map linkedHashMap = new LinkedHashMap<>();

linkedHashMap.put("z", 1);

linkedHashMap.put("a", 2);

linkedHashMap.put("b", 3);

System.out.println(linkedHashMap.keySet()); // 输出: [z, a, b]

3.3 TreeMap

// 排序的Map

Map treeMap = new TreeMap<>();

treeMap.put("orange", 1);

treeMap.put("apple", 2);

treeMap.put("banana", 3);

System.out.println(treeMap.keySet()); // 输出: [apple, banana, orange]

3.4 Hashtable vs HashMap

// Hashtable 是线程安全的

Map hashtable = new Hashtable<>();

hashtable.put("key", "value");

// HashMap 非线程安全,但性能更好

Map hashMap = new HashMap<>();

4. 集合的线程安全版本4.1 同步包装器

// 创建线程安全的集合

List syncList = Collections.synchronizedList(new ArrayList<>());

Set syncSet = Collections.synchronizedSet(new HashSet<>());

Map syncMap = Collections.synchronizedMap(new HashMap<>());

4.2 Concurrent 集合(Java 5+)

// 并发集合,性能更好

ConcurrentHashMap concurrentMap = new ConcurrentHashMap<>();

CopyOnWriteArrayList copyOnWriteList = new CopyOnWriteArrayList<>();

ConcurrentLinkedQueue concurrentQueue = new ConcurrentLinkedQueue<>();

5. 集合的性能比较5.1 List 性能比较操作

ArrayList

LinkedList

随机访问

O(1)

O(n)

头部插入

O(n)

O(1)

尾部插入

O(1)

O(1)

中间插入

O(n)

O(n)

删除

O(n)

O(1)

5.2 Set 性能比较操作

HashSet

TreeSet

LinkedHashSet

添加

O(1)

O(log n)

O(1)

包含

O(1)

O(log n)

O(1)

删除

O(1)

O(log n)

O(1)

有序

插入顺序

5.3 Map 性能比较操作

HashMap

TreeMap

LinkedHashMap

添加

O(1)

O(log n)

O(1)

获取

O(1)

O(log n)

O(1)

删除

O(1)

O(log n)

O(1)

有序

插入顺序

6. 集合的最佳实践6.1 选择合适的集合

// 根据需求选择集合类型

if (需要快速随机访问) {

return new ArrayList<>();

} else if (需要频繁插入删除) {

return new LinkedList<>();

} else if (需要去重) {

return new HashSet<>();

} else if (需要键值对) {

return new HashMap<>();

} else if (需要排序) {

return new TreeSet<>(); // 或 TreeMap

}

6.2 初始化容量

// 预估大小,避免扩容开销

List list = new ArrayList<>(1000);

Map map = new HashMap<>(1024, 0.75f);

6.3 使用增强for循环和迭代器

// 推荐写法

for (String item : collection) {

System.out.println(item);

}

// 需要删除时使用迭代器

Iterator iterator = list.iterator();

while (iterator.hasNext()) {

String item = iterator.next();

if (shouldRemove(item)) {

iterator.remove(); // 安全的删除方式

}

}

6.4 Java 8+ 新特性

// Stream API

List filtered = list.stream()

.filter(s -> s.startsWith("A"))

.map(String::toUpperCase)

.collect(Collectors.toList());

// computeIfAbsent

Map> map = new HashMap<>();

map.computeIfAbsent("key", k -> new ArrayList<>()).add("value");

7. 常见面试问题7.1 HashMap 的工作原理HashMap 基于数组+链表/红黑树实现,通过 hashCode() 计算存储位置,使用 equals() 解决哈希冲突。

7.2 ArrayList 和 LinkedList 的区别ArrayList 基于数组,随机访问快LinkedList 基于链表,插入删除快7.3 ConcurrentHashMap 的实现原理使用分段锁(Java 7)或 CAS + synchronized(Java 8),提高并发性能。

8. 总结Java 集合框架提供了丰富的数据结构和算法,理解它们的特性和适用场景对于编写高效代码至关重要:

关键要点:根据需求选择集合:考虑性能、线程安全、排序需求理解底层实现:知道不同集合的时间复杂度注意线程安全:多线程环境使用并发集合或同步包装器利用新特性:Java 8+ 的 Stream API 和 Lambda 表达式选择使用:List:需要有序、可重复的元素Set:需要去重、快速查找Map:需要键值对存储Queue:需要队列操作

相关推荐

世界杯首战,中国女足0比1惜败丹麦
365bet平台网址

世界杯首战,中国女足0比1惜败丹麦

📅 07-06 👁️ 2076
全美国爸妈都给娃玩的桌游,其实是它
365bet日博娱乐

全美国爸妈都给娃玩的桌游,其实是它

📅 07-19 👁️ 4711
公众号广告接单平台App哪个好?实测对比3款主流平台优劣