文章目录
- 前言
- 一、集合框架概述:为什么需要集合?
- 二、单列集合:元素的线性容器
-
- [2.1 List 集合:有序可重复的容器](#2.1 List 集合:有序可重复的容器)
- [2.2 Set 集合:无序不可重复的容器](#2.2 Set 集合:无序不可重复的容器)
- 三、双列集合:键值对的映射容器
-
- [3.1 Map 集合的核心特性](#3.1 Map 集合的核心特性)
- 四、单列集合与双列集合的关联与转换
-
- [4.1 Map 集合转单列集合](#4.1 Map 集合转单列集合)
- [4.2 单列集合模拟双列集合](#4.2 单列集合模拟双列集合)
- 总结
前言
大家好,我是程序员梁白开。
在 Java 开发中,集合框架是我们日常接触最频繁的工具之一,它就像一个功能强大的 "工具箱",帮我们高效管理和操作数据。而在这个工具箱中,单列集合和双列集合是两大核心分类,它们各自有着明确的适用场景和设计思想。本文将从底层原理、核心实现类、使用场景等多个维度,带你全面吃透这两类集合,帮你在实际开发中精准选型、高效编码。
一、集合框架概述:为什么需要集合?
在 Java 中,数组虽然可以存储多个元素,但它存在长度固定、只能存储同一类型元素、插入删除效率低等局限性。而集合框架的出现,正是为了解决这些问题,它提供了一系列灵活、高效的数据结构,支持动态扩容、多种数据存储方式和丰富的操作方法。
Java 集合框架主要分为两大体系:
- 单列集合:一次存储一个元素,顶层接口为Collection,我们常用的List、Set都属于这一体系。
- 双列集合:一次存储一对元素(键值对 Key-Value),顶层接口为Map,通过键来唯一标识一个值,常用的HashMap、TreeMap等都属于此类。
二、单列集合:元素的线性容器
单列集合的核心特点是每个位置只存放一个元素,它就像一个有序的货架,每个格子里放一件商品。根据元素是否有序、是否可重复,单列集合又分为List和Set两大分支。
2.1 List 集合:有序可重复的容器
List集合的核心特性是元素有序(插入顺序和存储顺序一致)且元素可重复,它允许通过索引来访问元素,就像数组一样灵活。
实战案例:ArrayList vs LinkedList 性能对比
java
public class ListPerformanceTest {
public static void main(String[] args) {
List<Integer> arrayList = new ArrayList<>();
List<Integer> linkedList = new LinkedList<>();
// 测试尾部插入
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
arrayList.add(i);
}
System.out.println("ArrayList尾部插入耗时:" + (System.currentTimeMillis() - startTime) + "ms");
startTime = System.currentTimeMillis();
for (int i = 0; i < 100000; i++) {
linkedList.add(i);
}
System.out.println("LinkedList尾部插入耗时:" + (System.currentTimeMillis() - startTime) + "ms");
// 测试中间插入
startTime = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
arrayList.add(5000, i);
}
System.out.println("ArrayList中间插入耗时:" + (System.currentTimeMillis() - startTime) + "ms");
startTime = System.currentTimeMillis();
for (int i = 0; i < 1000; i++) {
linkedList.add(5000, i);
}
System.out.println("LinkedList中间插入耗时:" + (System.currentTimeMillis() - startTime) + "ms");
}
}
运行结果分析:ArrayList 在尾部插入时效率和 LinkedList 相当,但在中间插入时,由于需要移动大量元素,效率远低于 LinkedList。这也印证了两者的适用场景差异。
2.2 Set 集合:无序不可重复的容器
Set集合的核心特性是元素无序(插入顺序和存储顺序不一定一致)且元素不可重复,它通过元素的equals()和hashCode()方法来保证唯一性,就像一个不允许重复的标签库。
关键知识点:HashSet 去重原理
HashSet 的去重机制依赖于两个方法:
- 先调用元素的hashCode()方法计算哈希值,确定元素在哈希表中的位置。
- 如果该位置已有元素,则调用equals()方法比较两个元素是否相等。
- 若equals()返回 true,则视为重复元素,不添加;否则以链表或红黑树的形式存储在该位置。
注意:如果我们自定义类作为 HashSet 的元素,必须重写hashCode()和equals()方法,否则无法保证去重效果。
三、双列集合:键值对的映射容器
双列集合的核心特点是以键值对(Key-Value)的形式存储元素,它就像一本字典,通过唯一的键(Key)可以快速找到对应的值(Value)。双列集合的顶层接口是Map,它不继承Collection接口,是一个独立的体系。
3.1 Map 集合的核心特性
- 键(Key)是唯一的,值(Value)可以重复。
- 一个键只能对应一个值,当存入相同键的键值对时,新值会覆盖旧值。
- 键和值都可以是任意引用类型数据(建议使用不可变类型作为 Key,如 String、Integer 等)。
TreeMap 支持自然排序(实现 Comparable 接口)和自定义排序(通过 Comparator 接口),以下是自定义排序的示例:
java
public class TreeMapCustomSort {
public static void main(String[] args) {
// 自定义排序:按字符串长度排序,长度相同则按字典序排序
Map<String, Integer> treeMap = new TreeMap<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int len1 = o1.length();
int len2 = o2.length();
if (len1 != len2) {
return len1 - len2; // 升序排列
} else {
return o1.compareTo(o2); // 字典序升序
}
}
});
treeMap.put("apple", 1);
treeMap.put("banana", 2);
treeMap.put("pear", 3);
treeMap.put("orange", 4);
// 遍历输出
for (Map.Entry<String, Integer> entry : treeMap.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
}
四、单列集合与双列集合的关联与转换
虽然单列集合和双列集合是两大独立体系,但它们之间可以通过一些方法进行转换,在实际开发中非常实用。
4.1 Map 集合转单列集合
- keySet():将 Map 的所有键转换为 Set 集合。
- values():将 Map 的所有值转换为 Collection 集合。
- entrySet():将 Map 的所有键值对转换为 Set 集合(每个元素是 Map.Entry 对象)。
示例代码:
java
Map<String, Integer> map = new HashMap<>();
map.put("Java", 1);
map.put("Python", 2);
map.put("C++", 3);
// 键转Set
Set<String> keySet = map.keySet();
// 值转Collection
Collection<Integer> values = map.values();
// 键值对转Set
Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
4.2 单列集合模拟双列集合
我们可以使用List存储自定义的键值对对象,来模拟 Map 的功能,这种方式在一些特殊场景下(如需要重复键)非常有用。
示例代码:
java
// 自定义键值对类
class KeyValue<K, V> {
private K key;
private V value;
// 构造方法、getter、setter省略
}
// 使用List模拟Map
List<KeyValue<String, Integer>> listMap = new ArrayList<>();
listMap.add(new KeyValue<>("Java", 1));
listMap.add(new KeyValue<>("Python", 2));
listMap.add(new KeyValue<>("Java", 3)); // 允许重复键
总结
Java 集合框架是 Java 开发的基础,单列集合和双列集合作为其中的核心,掌握它们的原理和用法是每个 Java 开发者的必备技能。
- 单列集合:适合存储单个元素,List注重有序可重复,Set注重无序不可重复。
- 双列集合:适合存储键值对映射关系,HashMap注重高效查找,TreeMap注重排序功能。