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

相关推荐
Deng9452013142 小时前
基于Python的职位画像系统设计与实现
开发语言·python·文本分析·自然语言处理nlp·scrapy框架·gensim应用
一只小青团5 小时前
Python之面向对象和类
java·开发语言
qq_529835356 小时前
ThreadLocal内存泄漏 强引用vs弱引用
java·开发语言·jvm
落笔画忧愁e6 小时前
扣子Coze飞书多维表插件添加数据记录
java·服务器·飞书
FreakStudio7 小时前
一文速通 Python 并行计算:13 Python 异步编程-基本概念与事件循环和回调机制
python·pycharm·协程·多进程·并行计算·异步编程
秋千码途8 小时前
小架构step系列08:logback.xml的配置
xml·java·logback
飞翔的佩奇8 小时前
Java项目:基于SSM框架实现的旅游协会管理系统【ssm+B/S架构+源码+数据库+毕业论文】
java·数据库·mysql·毕业设计·ssm·旅游·jsp
LCG元8 小时前
Windows实时内核驱动的数据捕获接口:高精度时钟与零拷贝的架构剖析
windows·架构
时来天地皆同力.8 小时前
Java面试基础:概念
java·开发语言·jvm
豌豆花下猫8 小时前
让 Python 代码飙升330倍:从入门到精通的四种性能优化实践
后端·python·ai