Java集合框架解析

一、集合框架概述

1. 集合框架体系结构

Java集合框架(Java Collections Framework, JCF)位于java.util包中,包含三大核心接口:

  • Collection :单列数据集合的根接口
    • List:有序可重复集合
    • Set:无序不可重复集合
    • Queue:队列集合
  • Map:双列键值对集合
  • Iterator:集合遍历接口

2. 核心接口继承关系

复制代码
Collection
├── List
│   ├── ArrayList
│   ├── LinkedList
│   └── Vector
│       └── Stack
├── Set
│   ├── HashSet
│   │   └── LinkedHashSet
│   └── SortedSet
│       └── TreeSet
└── Queue
    ├── Deque
    │   ├── ArrayDeque
    │   └── LinkedList
    └── PriorityQueue

Map
├── HashMap
│   └── LinkedHashMap
├── Hashtable
└── SortedMap
    └── TreeMap

二、基础集合使用

1. List接口实现

ArrayList
java 复制代码
// 创建ArrayList
List<String> arrayList = new ArrayList<>();

// 添加元素
arrayList.add("Java");
arrayList.add("Python");
arrayList.add(1, "C++"); // 在指定位置插入

// 访问元素
String lang = arrayList.get(0); // "Java"

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

// 删除元素
arrayList.remove("Python");
arrayList.remove(0);
LinkedList
java 复制代码
// 创建LinkedList
List<String> linkedList = new LinkedList<>();

// 特有方法
LinkedList<String> list = (LinkedList<String>) linkedList;
list.addFirst("First");
list.addLast("Last");
String first = list.getFirst();
String last = list.getLast();

2. Set接口实现

HashSet
java 复制代码
Set<String> hashSet = new HashSet<>();
hashSet.add("Apple");
hashSet.add("Banana");
hashSet.add("Apple"); // 重复元素不会被添加

System.out.println(hashSet); // [Apple, Banana]
TreeSet
java 复制代码
Set<Integer> treeSet = new TreeSet<>((a, b) -> b - a); // 自定义排序
treeSet.add(5);
treeSet.add(2);
treeSet.add(8);

System.out.println(treeSet); // [8, 5, 2]

3. Map接口实现

HashMap
java 复制代码
Map<String, Integer> hashMap = new HashMap<>();
hashMap.put("Alice", 25);
hashMap.put("Bob", 30);
hashMap.put("Charlie", 28);

// 获取值
int age = hashMap.get("Bob");

// 遍历
for (Map.Entry<String, Integer> entry : hashMap.entrySet()) {
    System.out.println(entry.getKey() + ": " + entry.getValue());
}
TreeMap
java 复制代码
Map<String, Integer> treeMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
treeMap.put("Banana", 3);
treeMap.put("apple", 5);
treeMap.put("Orange", 2);

System.out.println(treeMap); // {apple=5, Banana=3, Orange=2}

三、集合转换操作

1. 集合间相互转换

List ↔ Set
java 复制代码
// List转Set(去重)
List<String> listWithDuplicates = Arrays.asList("A", "B", "A", "C");
Set<String> set = new HashSet<>(listWithDuplicates); // [A, B, C]

// Set转List
List<String> listFromSet = new ArrayList<>(set);
数组 ↔ List
java 复制代码
// 数组转List
String[] array = {"Java", "Python", "C++"};
List<String> list = Arrays.asList(array); // 固定大小List
List<String> mutableList = new ArrayList<>(Arrays.asList(array));

// List转数组
String[] newArray = list.toArray(new String[0]);
Map ↔ Set
java 复制代码
// Map的key转Set
Set<String> keys = hashMap.keySet();

// Map的entry转Set
Set<Map.Entry<String, Integer>> entries = hashMap.entrySet();

// Set转Map(需要元素包含键值信息)
Set<Pair<String, Integer>> pairSet = new HashSet<>();
// ...添加元素
Map<String, Integer> mapFromSet = pairSet.stream()
    .collect(Collectors.toMap(Pair::getKey, Pair::getValue));

2. 不可变集合

Java 9+创建不可变集合
java 复制代码
List<String> immutableList = List.of("A", "B", "C");
Set<Integer> immutableSet = Set.of(1, 2, 3);
Map<String, Integer> immutableMap = Map.of("A", 1, "B", 2);

// 尝试修改会抛出UnsupportedOperationException
// immutableList.add("D"); // 错误
Collections工具类创建
java 复制代码
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
List<String> unmodifiableList = Collections.unmodifiableList(list);

四、集合流式处理(Java 8+)

1. 基本流操作

过滤与映射
java 复制代码
List<String> languages = Arrays.asList("Java", "Python", "C++", "JavaScript", "Ruby");

// 过滤长度大于3的元素
List<String> filtered = languages.stream()
    .filter(s -> s.length() > 3)
    .collect(Collectors.toList()); // [Java, Python, JavaScript, Ruby]

// 转换为大写
List<String> upperCase = languages.stream()
    .map(String::toUpperCase)
    .collect(Collectors.toList());
聚合操作
java 复制代码
// 统计
long count = languages.stream().count();
Optional<String> max = languages.stream().max(Comparator.naturalOrder());

// 求和
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream().reduce(0, Integer::sum);

2. 高级流操作

分组与分区
java 复制代码
// 按长度分组
Map<Integer, List<String>> groupByLength = languages.stream()
    .collect(Collectors.groupingBy(String::length));
// {2=[C++], 4=[Java, Ruby], 6=[Python], 10=[JavaScript]}

// 分区(满足条件的和其他的)
Map<Boolean, List<String>> partition = languages.stream()
    .collect(Collectors.partitioningBy(s -> s.startsWith("J")));
// {false=[Python, C++, Ruby], true=[Java, JavaScript]}
并行流
java 复制代码
// 顺序流
long count = languages.stream().filter(s -> s.length() > 3).count();

// 并行流(大数据量性能更好)
long parallelCount = languages.parallelStream().filter(s -> s.length() > 3).count();

五、集合与数组转换

1. 集合转数组

传统方式
java 复制代码
List<String> list = Arrays.asList("A", "B", "C");
String[] array = list.toArray(new String[0]); // 推荐使用空数组
Java 8+ Stream方式
java 复制代码
String[] array = list.stream().toArray(String[]::new);

2. 数组转集合

标准方式
java 复制代码
String[] array = {"A", "B", "C"};

// 固定大小List(不可修改)
List<String> asList = Arrays.asList(array);

// 可变List
List<String> mutableList = new ArrayList<>(Arrays.asList(array));
Java 8+ Stream方式
java 复制代码
List<String> list = Arrays.stream(array).collect(Collectors.toList());

// 去重
Set<String> set = Arrays.stream(array).collect(Collectors.toSet());

六、集合框架底层实现

1. ArrayList实现原理

  • 底层结构 :动态数组Object[] elementData
  • 扩容机制
    • 默认初始容量10
    • 扩容时newCapacity = oldCapacity + (oldCapacity >> 1)(约1.5倍)
    • 最大容量Integer.MAX_VALUE - 8
  • 特点
    • 随机访问快(O(1))
    • 插入删除慢(平均O(n))
    • 线程不安全

2. LinkedList实现原理

  • 底层结构 :双向链表

    java 复制代码
    private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;
        // ...
    }
  • 特点

    • 插入删除快(O(1))
    • 随机访问慢(O(n))
    • 实现了List和Deque接口

3. HashMap实现原理(Java 8+)

  • 底层结构 :数组+链表+红黑树

    • 默认初始容量16,负载因子0.75
    • 链表长度>8且数组长度≥64时,链表转红黑树
    • 树节点数<6时,红黑树转链表
  • 哈希计算

    java 复制代码
    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }
  • 扩容机制

    • 容量变为2倍
    • 重新计算节点位置:newTab[e.hash & (newCap - 1)]

4. TreeMap实现原理

  • 底层结构:红黑树(自平衡二叉查找树)
  • 排序规则
    • 自然排序(元素实现Comparable)
    • 或通过Comparator自定义排序
  • 特点
    • 查找、插入、删除时间复杂度O(log n)
    • 保持元素有序

七、集合框架性能比较

1. List实现比较

操作 ArrayList LinkedList
get(int) O(1) O(n)
add(E) 平均O(1) O(1)
add(int, E) O(n) O(1)
remove(int) O(n) O(1)
内存占用 较小(仅数组) 较大(节点开销)

2. Set实现比较

特性 HashSet LinkedHashSet TreeSet
底层实现 HashMap LinkedHashMap TreeMap
顺序 无序 插入顺序 自然/自定义排序
时间复杂度 O(1) O(1) O(log n)
线程安全

3. Map实现比较

特性 HashMap LinkedHashMap TreeMap Hashtable
底层实现 数组+链表+红黑树 链表+哈希表 红黑树 数组+链表
顺序 无序 插入/访问顺序 键排序 无序
线程安全
允许null

八、线程安全集合

1. 传统线程安全集合

Vector和Hashtable
java 复制代码
// 线程安全但性能较差
Vector<String> vector = new Vector<>();
Hashtable<String, Integer> hashtable = new Hashtable<>();
Collections.synchronizedXXX
java 复制代码
List<String> syncList = Collections.synchronizedList(new ArrayList<>());
Map<String, Integer> syncMap = Collections.synchronizedMap(new HashMap<>());

2. Java 5+并发集合

CopyOnWriteArrayList
java 复制代码
// 写时复制,适合读多写少场景
List<String> cowList = new CopyOnWriteArrayList<>();
ConcurrentHashMap
java 复制代码
// 分段锁实现高并发
Map<String, Integer> concurrentMap = new ConcurrentHashMap<>();
BlockingQueue
java 复制代码
// 阻塞队列
BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
queue.put("item");  // 阻塞直到空间可用
String item = queue.take();  // 阻塞直到元素可用

九、最佳实践

1. 集合选择策略

  • 需要快速随机访问:ArrayList
  • 频繁插入删除:LinkedList
  • 去重存储:HashSet/LinkedHashSet/TreeSet
  • 键值存储:HashMap/LinkedHashMap/TreeMap
  • 线程安全:ConcurrentHashMap/CopyOnWriteArrayList

2. 性能优化建议

  1. 初始化合适容量

    java 复制代码
    new ArrayList<>(100);  // 避免频繁扩容
    new HashMap<>(32, 0.75f);
  2. 使用forEach代替迭代器

    java 复制代码
    // Java 8+
    list.forEach(System.out::println);
    map.forEach((k, v) -> System.out.println(k + ": " + v));
  3. 避免在循环中修改集合

    java 复制代码
    // 错误方式 - 可能抛出ConcurrentModificationException
    for (String item : list) {
        if (condition) {
            list.remove(item);
        }
    }
    
    // 正确方式 - 使用迭代器
    Iterator<String> it = list.iterator();
    while (it.hasNext()) {
        if (condition) {
            it.remove();
        }
    }

3. 常见陷阱

  1. Arrays.asList返回固定大小List

    java 复制代码
    List<String> list = Arrays.asList("A", "B", "C");
    // list.add("D"); // 抛出UnsupportedOperationException
  2. 集合元素可变性问题

    java 复制代码
    Set<Date> dates = new HashSet<>();
    Date now = new Date();
    dates.add(now);
    now.setTime(now.getTime() + 1000); // 修改后影响集合行为
  3. equals和hashCode不一致

    java 复制代码
    class Person {
        String name;
        // 如果只重写equals不重写hashCode,会导致HashSet/HashMap行为异常
    }

十、Java 8-17集合新特性

1. Java 8增强

  • Stream API:函数式集合操作

  • HashMap性能提升:链表转红黑树

  • 新增方法

    java 复制代码
    map.computeIfAbsent(key, k -> new ArrayList<>()).add(value);
    list.removeIf(e -> e.length() > 5);

2. Java 9增强

  • 工厂方法创建不可变集合

    java 复制代码
    List<String> list = List.of("A", "B", "C");
    Set<Integer> set = Set.of(1, 2, 3);
    Map<String, Integer> map = Map.of("A", 1, "B", 2);

3. Java 10增强

  • copyOf创建不可变集合

    java 复制代码
    List<String> copy = List.copyOf(originalList);

4. Java 16增强

  • Stream.toList()简化

    java 复制代码
    List<String> list = stream.toList(); // 替代collect(Collectors.toList())

通过深入理解Java集合框架的设计原理和使用方法,开发者可以编写出更高效、更健壮的代码。集合框架是Java编程中最常用的工具之一,掌握其特性和最佳实践对提高开发效率至关重要。

相关推荐
思绪无限7 分钟前
YOLOv5至YOLOv12升级:血细胞检测系统的设计与实现(完整代码+界面+数据集项目)
人工智能·python·深度学习·目标检测·计算机视觉·yolov12·血细胞检测
无巧不成书021833 分钟前
零基础Java网络编程全解:从核心概念到Socket实战,一文打通Java网络通信
java·开发语言·网络
aq55356001 小时前
Workstation神技:一键克隆调试环境
java·开发语言
skywalk81632 小时前
发现Kotti项目的python包Beaker 存在安全漏洞
开发语言·网络·python·安全
今天你TLE了吗2 小时前
LLM到Agent&RAG——AI知识点概述 第六章:Function Call函数调用
java·人工智能·学习·语言模型·大模型
Rcnhtin2 小时前
RocketMQ
java·linux·rocketmq
天天进步20152 小时前
Python全栈项目:从零构建基于 Django 的知识管理系统(KMS)
开发语言·python·django
JH30732 小时前
RedLock-红锁
java·redis
珎珎啊2 小时前
Python3 迭代器与生成器
开发语言·python
思绪无限3 小时前
YOLOv5至YOLOv12升级:金属锈蚀检测系统的设计与实现(完整代码+界面+数据集项目)
人工智能·python·深度学习·目标检测·计算机视觉·yolov12