在 Java 中,集合 是一种存储元素的容器,允许快速查找特定元素。Java 提供了丰富的集合实现类和接口,每个接口都有其特定的功能。
选择合适的集合需要考虑以下因素:
接口 | 特点 | 典型实现类 | 时间复杂度 |
---|---|---|---|
List | 有序,可重复 | ArrayList/LinkedList | 随机访问O(1)/O(n) |
Set | 无序,唯一 | HashSet/TreeSet | 添加/查找O(1)/O(logn) |
Map | 键值对,键唯一 | HashMap/TreeMap | 添加/查找O(1)/O(logn) |
Queue | 先进先出(FIFO) | LinkedList/PriorityQueue | 入队出队O(1)/O(logn) |
// 创建与基本操作
List<String> list = new ArrayList<>();
list.add("Apple"); // 添加元素
list.add(0, "Banana"); // 指定位置插入
String fruit = list.get(1); // 获取元素(索引从0开始)
list.remove("Apple"); // 删除元素
// 遍历方式
for (int i = 0; i < list.size(); i++) { // 随机访问
System.out.println(list.get(i));
}
for (String s : list) { // foreach遍历
System.out.println(s);
}
// 转换为数组
String[] array = list.toArray(new String[0]);
特点:
List<Integer> linkedList = new LinkedList<>();
linkedList.add(10);
linkedList.addFirst(5); // 头部插入
linkedList.addLast(20); // 尾部插入
// 使用迭代器高效删除
Iterator<Integer> it = linkedList.iterator();
while (it.hasNext()) {
if (it.next() == 10) {
it.remove(); // 安全删除
}
}
特点:
Set<String> names = new HashSet<>();
names.add("Alice");
names.add("Bob");
names.add("Alice"); // 重复元素被忽略
// 快速判断存在性
if (names.contains("Bob")) {
System.out.println("Bob存在");
}
// 遍历无序
for (String name : names) {
System.out.println(name); // 输出顺序不确定
}
实现原理:
Set<Integer> scores = new TreeSet<>();
scores.add(90);
scores.add(85);
scores.add(95);
// 自动排序遍历
for (int score : scores) {
System.out.println(score); // 输出85,90,95
}
// 范围查询
Set<Integer> subSet = ((TreeSet<Integer>)scores).subSet(85, true, 90, true);
特点:
Map<String, Integer> map = new HashMap<>();
map.put("Apple", 10);
map.put("Banana", 5);
// 获取值(注意空指针)
Integer count = map.get("Apple");
// 遍历EntrySet
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
// Java8遍历方式
map.forEach((k, v) -> System.out.println(k + " => " + v));
重要特性:
Map<String, Integer> orderedMap = new LinkedHashMap<>();
orderedMap.put("A", 1);
orderedMap.put("C", 3);
orderedMap.put("B", 2);
// 保持插入顺序遍历
orderedMap.forEach((k, v) -> System.out.println(k)); // 输出A,C,B
应用场景:需要保持插入顺序的缓存系统
List<Integer> numbers = Arrays.asList(3,1,4,1,5,9);
// 排序
Collections.sort(numbers); // [1,1,3,4,5,9]
// 洗牌
Collections.shuffle(numbers);
// 不可变集合
List<Integer> immutable = Collections.unmodifiableList(numbers);
// 同步包装
List<Integer> syncList = Collections.synchronizedList(numbers);
// 快速初始化List
List<String> cities = new ArrayList<>() {{
add("北京");
add("上海");
add("广州");
}};
// 使用Stream初始化
List<Integer> nums = Stream.of(1,2,3).collect(Collectors.toList());
需求场景 | 推荐实现类 | 理由 |
---|---|---|
频繁随机访问 | ArrayList | O(1)访问效率 |
频繁插入删除 | LinkedList | O(1)插入删除 |
去重存储 | HashSet | O(1)查找 |
需要排序 | TreeSet | 自动排序 |
键值对快速查找 | HashMap | 最优哈希表实现 |
需要插入顺序 | LinkedHashMap | 维护插入顺序 |
new ArrayList<>(100); // 指定初始容量
IntArrayList (Eclipse Collections)
// ArrayList使用普通for更快
for (int i=0; i<list.size(); i++) {}
// LinkedList使用迭代器更优
Iterator<Integer> it = list.iterator();
方案 | 优点 | 缺点 |
---|---|---|
Vector | 简单易用 | 全表锁,性能差 |
Collections.synchronizedXXX | 灵活包装 | 同Vector |
ConcurrentHashMap | 分段锁,高并发 | 不保证强一致性 |
CopyOnWriteArrayList | 读无锁,写时复制 | 内存消耗大,适合读多写少 |
List<String> list = new ArrayList<>(Arrays.asList("A", "B", "C"));
// 错误方式(抛出异常)
for (String s : list) {
if (s.equals("B")) {
list.remove(s);
}
}
// 正确方式:使用迭代器删除
Iterator<String> it = list.iterator();
while (it.hasNext()) {
if (it.next().equals("B")) {
it.remove();
}
}
特性 | HashMap | HashTable |
---|---|---|
线程安全 | 否 | 是 |
null支持 | 允许key/value为null | 不允许 |
迭代器 | fail-fast | 不保证 |
性能 | 更高 | 较低 |
通过本文的学习,您已经掌握了Java集合框架的核心知识。关键要点总结:
建议通过以下步骤巩固学习:
掌握集合框架是Java开发的基石,合理选择数据结构能让您的程序更高效、更健壮!