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编程中最常用的工具之一,掌握其特性和最佳实践对提高开发效率至关重要。

相关推荐
zhang238390615416 分钟前
IDEA add gitlab account 提示
java·gitlab·intellij-idea·idea
橘猫云计算机设计19 分钟前
springboot基于hadoop的酷狗音乐爬虫大数据分析可视化系统(源码+lw+部署文档+讲解),源码可白嫖!
数据库·hadoop·spring boot·爬虫·python·数据分析·毕业设计
YOULANSHENGMENG24 分钟前
linux 下python 调用c++的动态库的方法
c++·python
牛马baby34 分钟前
Java高频面试之并发编程-07
java·开发语言·面试
SsummerC41 分钟前
【leetcode100】零钱兑换Ⅱ
数据结构·python·算法·leetcode·动态规划
卓怡学长1 小时前
w304基于HTML5的民谣网站的设计与实现
java·前端·数据库·spring boot·spring·html5
YONG823_API1 小时前
深度探究获取淘宝商品数据的途径|API接口|批量自动化采集商品数据
java·前端·自动化
一眼青苔1 小时前
切割PDF使用python,库PyPDF2
服务器·python·pdf
yzhSWJ1 小时前
Spring Boot中自定义404异常处理问题学习笔记
java·javascript
电商数据girl1 小时前
产品经理对于电商接口的梳理||电商接口文档梳理与接入
大数据·数据库·python·自动化·产品经理