Java 集合类概述
Java 集合类是Java编程语言中最重要的基础组件之一,它提供了一套完善的框架来存储和操作对象组。集合类位于java.util包中,包含了各种数据结构的实现,如列表、集合、队列和映射等。
集合类的主要作用
Java集合类主要解决以下问题:
- 提供高效的数据存储方式
- 简化数据操作流程
- 实现常见数据结构算法
- 保证线程安全(部分实现)
集合框架的层次结构
Java集合框架主要分为两大类:
1. Collection接口:代表一组对象
- List:有序可重复集合
- Set:无序不可重复集合
- Queue:队列实现
- Map接口:键值对映射关系
- 不继承Collection接口
- 提供基于键的数据访问
Java集合类核心接口详解
List接口及其实现类
List是Java集合类中最常用的接口之一,它代表有序的、可重复的元素集合。
ArrayList
List<String> arrayList = new ArrayList<>();
arrayList.add("Java");
arrayList.add("Collection");
特点:
- 基于动态数组实现
- 随机访问速度快(O(1))
- 插入删除效率较低(平均O(n))
- 非线程安全
LinkedList
List<Integer> linkedList = new LinkedList<>();
linkedList.add(1);
linkedList.add(2);
特点:
- 基于双向链表实现
- 插入删除效率高(O(1))
- 随机访问效率低(O(n))
- 实现了Deque接口
Set接口及其实现类
Set接口表示不包含重复元素的集合,是数学中集合的抽象。
HashSet
Set<String> hashSet = new HashSet<>();
hashSet.add("Apple");
hashSet.add("Banana");
特点:
- 基于HashMap实现
- 元素无序
- 添加、删除、查找效率高(O(1))
- 允许null元素
TreeSet
Set<Integer> treeSet = new TreeSet<>();
treeSet.add(5);
treeSet.add(2);
特点:
- 基于TreeMap实现
- 元素按自然顺序或Comparator排序
- 基本操作时间复杂度O(log n)
- 不允许null元素
Map接口及其实现类
Map接口表示键值对映射,键不可重复。
HashMap
Map<String, Integer> hashMap = new HashMap<>();
hashMap.put("Java", 1);
hashMap.put("Collection", 2);
特点:
- 基于哈希表实现
- 键值对无序存储
- 允许null键和null值
- 非线程安全
TreeMap
Map<String, String> treeMap = new TreeMap<>();
treeMap.put("B", "Banana");
treeMap.put("A", "Apple");
特点:
- 基于红黑树实现
- 按键的自然顺序或Comparator排序
- 不允许null键(但允许null值)
- 基本操作时间复杂度O(log n)
Java集合类高级特性
迭代器(Iterator)与增强for循环
Java集合类提供了统一的遍历方式:
List<String> list = Arrays.asList("A", "B", "C");
// 使用迭代器
Iterator<String> it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
// 使用增强for循环
for(String s : list) {
System.out.println(s);
}
泛型在集合类中的应用
泛型保证了集合的类型安全:
List<String> stringList = new ArrayList<>(); // 正确
// stringList.add(1); // 编译错误
集合工具类Collections
Collections类提供了众多静态方法操作集合:
List<Integer> numbers = Arrays.asList(3,1,4,1,5,9);
Collections.sort(numbers); // 排序
Collections.reverse(numbers); // 反转
Collections.shuffle(numbers); // 随机打乱
Java集合类性能比较与选择策略
各集合类时间复杂度对比
操作 | ArrayList | LinkedList | HashSet | TreeSet | HashMap | TreeMap |
---|---|---|---|---|---|---|
添加 | O(1) | O(1) | O(1) | O(log n) | O(1) | O(log n) |
删除 | O(n) | O(1) | O(1) | O(log n) | O(1) | O(log n) |
查找 | O(1) | O(n) | O(1) | O(log n) | O(1) | O(log n) |
按顺序访问 | O(1) | O(1) | 不支持 | O(log n) | 不支持 | O(log n) |
集合类选择指南
- 需要快速随机访问:选择ArrayList
- 频繁插入删除:选择LinkedList
- 需要唯一元素:选择HashSet或TreeSet
- 需要键值对存储:选择HashMap或TreeMap
- 需要排序功能:选择TreeSet或TreeMap
- 需要线程安全:考虑ConcurrentHashMap或Collections.synchronizedXXX
Java 8对集合类的增强
Stream API操作集合
List<String> names = Arrays.asList("John", "Alice", "Bob");
// 过滤并打印
names.stream()
.filter(name -> name.startsWith("A"))
.forEach(System.out::println);
Lambda表达式简化集合操作
List<Integer> numbers = Arrays.asList(1,2,3,4,5);
numbers.forEach(number -> System.out.println(number * 2));
新的集合方法
Map<String, Integer> map = new HashMap<>();
map.putIfAbsent("Java", 1); // 仅当键不存在时放入
map.computeIfPresent("Java", (k, v) -> v + 1); // 键存在时计算新值
常见问题与最佳实践
Java集合类使用中的常见错误
-
并发修改异常
java List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c")); for(String s : list) { if(s.equals("b")) { list.remove(s); // 抛出ConcurrentModificationException } }
解决方案:使用迭代器的remove方法 -
不正确的equals和hashCode实现
- 作为HashMap键的对象必须正确实现这两个方法
- 相等的对象必须有相同的hashCode
性能优化建议
-
初始化合适容量
java // 如果知道大约需要存储1000个元素 Map<String, Integer> map = new HashMap<>(1000);
-
选择合适集合类
- 小数据集:ArrayList通常足够
-
大数据集:考虑LinkedList或特定场景优化的集合
-
避免频繁的装箱拆箱
java // 使用原始类型专用集合 IntArrayList (第三方库如Eclipse Collections)
总结
Java集合类是Java开发中不可或缺的工具,理解各种集合类的特点、适用场景和性能特征对于编写高效、健壮的代码至关重要。从基本的ArrayList、HashMap到Java 8引入的Stream API,集合框架在不断进化,为开发者提供了更强大的数据处理能力。
在实际开发中,应根据具体需求选择合适的集合类,并遵循最佳实践以避免常见陷阱。随着Java版本的更新,集合类也在不断加入新特性,持续学习和掌握这些变化将帮助开发者更好地利用Java集合框架的强大功能。