在 Java 编程中,处理批量数据是高频需求。数组虽能存储数据,但存在长度固定、操作繁琐等局限。集合(Collections) 作为 Java 提供的灵活数据容器,完美解决了这些问题 —— 它支持动态扩容,提供丰富的增删改查方法,是处理多元素数据的核心工具。今天就带大家从零梳理集合体系,重点解析 Collection 接口、Map 接口、二者差异及相关工具类,新手也能轻松上手。
一、集合基础:什么是集合?为什么用集合?
1. 集合的定义
集合是 java.util 包下用于存储多个对象的容器(注意:集合不能直接存基本数据类型,需通过包装类转换)。它隐藏了底层数据结构(如数组、链表、哈希表)的实现细节,提供统一的操作接口,让开发者无需关心 “如何存储”,只需专注 “如何使用”。
2. 集合 vs 数组:核心优势对比
特性数组(Array)集合(Collection/Map)长度特性长度固定,创建后不可修改长度动态可变,自动扩容存储类型仅支持同一类型元素可存储不同类型对象(建议统一类型)操作能力仅支持索引访问,无内置方法提供增删改查、排序、遍历等方法存储对象可存基本类型或对象仅存对象(基本类型需装箱)实例:数组的局限与集合的便捷性
// 数组:添加元素需手动扩容,操作繁琐
int[] arr = new int[3];
arr[0] = 1;
arr[1] = 2;
arr[2] = 3;
// 想添加第4个元素,需新建数组并复制
int[] newArr = new int[arr.length + 1];
System.arraycopy(arr, 0, newArr, 0, arr.length);
newArr[3] = 4;
// 集合:动态扩容,添加元素直接调用方法
List
list.add(1);
list.add(2);
list.add(3);
list.add(4); // 无需关心容量,直接添加
System.out.println("集合元素:" + list); // 输出:[1, 2, 3, 4]
二、集合体系核心:两大顶层接口
Java 集合体系以 Collection 接口和 Map 接口为核心,二者分支覆盖了所有常用数据结构。先通过简化体系图建立整体认知:
java.util
├─ Collection(存储单个元素的集合)
│ ├─ List(有序、可重复)
│ │ ├─ ArrayList(数组实现,查询快)
│ │ └─ LinkedList(链表实现,增删快)
│ ├─ Set(无序、不可重复)
│ │ ├─ HashSet(哈希表实现,查询快)
│ │ └─ TreeSet(红黑树实现,可排序)
│ └─ Queue(队列,先进先出)
│ └─ LinkedList(兼作队列实现)
└─ Map(存储键值对的集合)
├─ HashMap(哈希表实现,查询快)
├─ LinkedHashMap(链表+哈希表,有序)
└─ TreeMap(红黑树实现,可排序)
三、Collection 接口:存储单个元素的 “线性容器”
Collection 接口是所有单个元素集合的父接口,定义了一套统一的操作规范,其子类(List、Set)需实现这些方法。
1. Collection 接口的常用方法
无论 List 还是 Set,都支持以下核心操作(以 List 为例演示):
方法名功能add(E e)添加元素,返回是否成功remove(Object o)删除指定元素,返回是否成功contains(Object o)判断是否包含指定元素size()获取元素个数isEmpty()判断集合是否为空clear()清空所有元素iterator()获取迭代器,用于遍历实例:Collection 方法的基本使用
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo {
public static void main(String[] args) {
// 创建Collection实现类对象(ArrayList)
Collection
// 添加元素
coll.add("Java");
coll.add("Python");
coll.add("C++");
System.out.println("添加后:" + coll); // [Java, Python, C++]
// 判断是否包含元素
System.out.println("包含Java?" + coll.contains("Java")); // true
// 删除元素
coll.remove("Python");
System.out.println("删除后:" + coll); // [Java, C++]
// 遍历集合(增强for循环)
System.out.print("遍历元素:");
for (String lang : coll) {
System.out.print(lang + " "); // Java C++
}
// 清空集合
coll.clear();
System.out.println("\n清空后为空?" + coll.isEmpty()); // true
}
}
2. Collection 的核心子接口:List 与 Set
Collection 的两大子接口特性差异显著,决定了不同的使用场景:
(1)List 接口:有序、可重复的集合
“有序” 指元素存储顺序与添加顺序一致;“可重复” 指允许存储相同元素(包括null)。常用实现类为 ArrayList 和 LinkedList。
实现类底层结构优势劣势适用场景ArrayList动态数组随机访问快(索引定位)增删慢(需移动元素)查多改少(如数据展示)LinkedList双向链表增删快(仅改指针)随机访问慢(需遍历)增删多查少(如队列)实例:ArrayList 与 LinkedList 的差异
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class ListDemo {
public static void main(String[] args) {
// ArrayList:查询快
List
arrayList.add("A");
arrayList.add("B");
String elem = arrayList.get(1); // 直接通过索引获取,效率高
System.out.println("ArrayList索引1的元素:" + elem); // B
// LinkedList:增删快
List
linkedList.add("X");
linkedList.add("Y");
linkedList.add(1, "Z"); // 在中间插入,仅修改指针
System.out.println("LinkedList插入后:" + linkedList); // [X, Z, Y]
}
}
(2)Set 接口:无序、不可重复的集合
“无序” 指元素存储顺序与添加顺序无关(HashSet);“不可重复” 指通过 equals() 和 hashCode() 判断元素是否相同,重复元素会被过滤。常用实现类为 HashSet 和 TreeSet。
实现类底层结构特性适用场景HashSet哈希表无序、查询快去重、快速查找TreeSet红黑树可排序(自然 / 自定义)需排序的去重场景实例:Set 的去重特性
import java.util.HashSet;
import java.util.Set;
public class SetDemo {
public static void main(String[] args) {
Set
set.add(10);
set.add(20);
set.add(10); // 重复元素,添加失败
set.add(30);
System.out.println("Set集合元素:" + set); // [10, 20, 30](无序、去重)
}
}
四、Map 接口:存储键值对的 “字典容器”
Map 接口与 Collection 接口平级,专门存储键值对(Key-Value)数据,类似现实中的字典 ——“键(Key)” 唯一,“值(Value)” 可重复,通过键能快速定位值。
1. Map 接口的核心特性
键唯一:同一 Map 中不能有重复键,重复添加会覆盖原 value;值可重复:不同键可对应相同值;键值关联:查询效率依赖底层结构(如 HashMap 查询时间复杂度为 O(1))。
2. Map 接口的常用方法
方法名功能put(K key, V value)添加键值对,返回旧 valueget(Object key)通过键获取值,无则返回 nullremove(Object key)通过键删除键值对,返回旧 valuecontainsKey(K key)判断是否包含指定键keySet()获取所有键的 Set 集合entrySet()获取所有键值对的 Set 集合size()/isEmpty()元素个数 / 是否为空实例:Map 的基本操作与遍历
import java.util.HashMap;
import java.util.Map;
public class MapDemo {
public static void main(String[] args) {
// 创建Map实现类对象(HashMap)
Map
// 添加键值对
scoreMap.put("张三", 90);
scoreMap.put("李四", 85);
scoreMap.put("张三", 95); // 重复键,覆盖原value
System.out.println("添加后:" + scoreMap); // {张三=95, 李四=85}
// 通过键获取值
System.out.println("张三的分数:" + scoreMap.get("张三")); // 95
// 遍历Map(推荐entrySet方式,效率高)
System.out.print("键值对遍历:");
for (Map.Entry
String key = entry.getKey();
Integer value = entry.getValue();
System.out.print(key + ":" + value + " "); // 张三:95 李四:85
}
}
}
3. Map 的常用实现类
实现类底层结构特性适用场景HashMap哈希表无序、查询快普通键值对存储(最常用)LinkedHashMap链表 + 哈希表有序(添加顺序)需保持插入顺序的场景TreeMap红黑树按键排序需排序的键值对场景五、核心对比:Collection 与 Map 的区别
很多初学者容易混淆 Collection 和 Map,二者核心差异体现在存储结构和使用场景:
对比维度Collection 接口Map 接口存储单元单个元素(E)键值对(Key-Value)核心特性List 有序可重复 / Set 无序不可重复键唯一、值可重复遍历方式增强 for / 迭代器遍历键 / 值 / 键值对核心方法add(E)/remove(Object)put(K,V)/get(K)使用场景存储独立元素(如列表、集合)存储键值关联数据(如配置表)一句话总结:存 “单个元素的集合” 用 Collection,存 “键值对应的数据” 用 Map。
六、集合工具类:Collections(带s的工具类)
java.util.Collections 是集合的 “辅助工具”——所有方法都是静态的,无需创建对象,提供排序、查找、同步化等便捷操作,专门用于处理 Collection 和 Map。
1. Collections 的常用方法
(1)排序与查找
sort(List
(2)其他实用方法
reverse(List> list):反转集合元素;shuffle(List> list):随机打乱元素;synchronizedList(List
实例:Collections 工具类的使用
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class CollectionsToolDemo {
public static void main(String[] args) {
List
list.add(3);
list.add(1);
list.add(2);
System.out.println("原始集合:" + list); // [3, 1, 2]
// 自然排序
Collections.sort(list);
System.out.println("排序后:" + list); // [1, 2, 3]
// 二分查找
int index = Collections.binarySearch(list, 2);
System.out.println("元素2的索引:" + index); // 1
// 随机打乱
Collections.shuffle(list);
System.out.println("打乱后:" + list); // 如 [2, 3, 1]
}
}
2. 关键区别:Collection 与 Collections
这是初学者的高频坑点,二者仅差一个s,但本质完全不同:
对比维度Collection(无s)Collections(有s)类型接口(Interface)工具类(Class)核心作用定义集合的顶层规范提供操作集合的静态方法使用方式被子类实现(如 ArrayList)直接调用静态方法(如 Collections.sort())方法特性抽象方法,需子类实现静态方法,无需创建对象一句话区分:Collection 是 “集合的模板”,Collections 是 “操作集合的工具”。
七、避坑指南与总结
1. 常见坑点
集合存储的是对象引用:修改集合外的对象,集合内的元素也会变化;String 的不可变性与集合:Set
2. 集合选择技巧
需有序可重复:用 ArrayList(查多)或 LinkedList(增删多);需无序去重:用 HashSet;需排序去重:用 TreeSet;需键值关联:用 HashMap(普通场景)、LinkedHashMap(需顺序)、TreeMap(需排序);需线程安全:用 Vector(List)、Hashtable(Map)或 Collections.synchronizedXXX()。
希望这篇文章可以让你掌握接口和实现类的特性。