List、Set、Map:三个装数据的容器,到底啥区别?怎么遍历?
学 Java 集合,一定会碰到这三个集合:
List、Set、Map。 它们都是用来"装数据"的,但完全不同,遍历方式也不一样。 这篇用生活场景,可能会帮助你。
一、先了解基础异同
List与Set相同的地方,他们都是单列的集合,而Map是双列的集合。
List、Set :一次装一个元素,像一列队伍。 Map:一次装一对(键 + 值),像一本通讯录。
怎么理解呢?接下来我们细细来讲。
二、List:有序的队伍(可重复)
一句话:就像排队一样,有顺序,可以重复,也可以通过某一个序号找到某一个元素。
java
List<String> list = new ArrayList<>();
list.add("张三");
list.add("李四");
list.add("张三"); // 可以重复,排两次队
特点 :
有序 :谁先来谁站前面,位置固定
可重复 :同样的元素可以装多个
有索引:可以用下标精确找到第几个
生活类比:排队买奶茶,队伍有序、可以有两个一样的人名、你能说出第 3 个是谁。
常用实现 :ArrayList像数组,查得快、LinkedList像链表,增删快
三、Set:一伙不重复的人(无序)
一句话:像一群人去开会,每个人只能来一次,重复的自动被挡在外面。
java
Set<String> set = new HashSet<>();
set.add("张三");
set.add("李四");
set.add("张三"); // 加不进去!张三已经存在
特点 :
不可重复 :同样的元素只能有一个,自动去重
无序 :装进去的顺序和取出来的顺序可能不一样
没有索引:不分先后,不能知道序号几是谁
生活类比:开会点名,同一个人只能点一次,多喊"张三"不会多出一个人。
常用实现 :HashSet快,但不保证顺序、LinkedHashSet保序、TreeSet自动排序。
四、Map:一本通讯录(键 + 值)
一句话:就像手机通讯录,一个名字(键)对应一个号码(值),靠名字查号码。
java
Map<String, String> map = new HashMap<>();
map.put("张三", "13800138000");
map.put("李四", "13900139000");
// 靠键(名字)找到值(号码)
String phone = map.get("张三"); // 返回 "13800138000"
特点 :
键值对 :一个键对应一个值,成双成对地存
键不能重复 :像人名不能重名,重了会覆盖
按键查找快 :你知道名字,就能立刻查到号码
不是 Collection:它自己是一个独立家族
生活类比:通讯录------你查"张三",马上得到他的电话;存一个"张三",不会存两个张三。
常用实现 :HashMap快,无序、LinkedHashMap保序、TreeMap按键排序。
五、一张表,对比三个集合
| List | Set | Map | |
|---|---|---|---|
| 存什么 | 一个元素 | 一个元素 | 键 + 值(一对) |
| 顺序 | 有序 | 无序(一般) | 无序(一般) |
| 能否重复 | 能重复 | 不能重复 | 键不能重复,值可以 |
| 有无索引 | 有(下标) | 无 | 无(用键查找) |
| 生活类比 | 排队 | 点名去重 | 通讯录 |
| 常用实现 | ArrayList / LinkedList | HashSet / TreeSet | HashMap / TreeMap |
六、遍历方式
1. List 的遍历
java
List<String> list = new ArrayList<>(List.of("张三", "李四", "王五"));
// 方式一:普通 for,用下标(List 独有)
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// 方式二:增强 for(最常用)
for (String name : list) {
System.out.println(name);
}
// 方式三:迭代器(Iterator)
Iterator<String> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
2. Set 的遍历
java
Set<String> set = new HashSet<>(Set.of("张三", "李四"));
// 方式一:增强 for(最常用)
for (String name : set) {
System.out.println(name);
}
// 方式二:迭代器
Iterator<String> it = set.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
因为set没有下标,所以无法使用普通的for循环遍历。
3. Map的遍历
java
Map<String, String> map = new HashMap<>();
map.put("张三", "138...");
map.put("李四", "139...");
// 方式一:遍历所有键(keySet),再拿键去取值
for (String name : map.keySet()) {
System.out.println(name + " -> " + map.get(name));
}
// 方式二:遍历所有键值对(entrySet),最常用
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + " -> " + entry.getValue());
}
// 方式三:只遍历所有值(values)
for (String phone : map.values()) {
System.out.println(phone);
}
最后,一句话总结
List 是排队(有序可重复),Set 是点名(去重),Map 是通讯录(键查值)。
遍历记住:List 能 for+下标,Set 不能,Map 最常用
entrySet()。