所谓诚其意者,毋自欺也。如恶恶臭,如好好色,此之谓自谦。故君子必慎其独也。

写在前面

从一年半之前开发的spring boot贪吃蛇来看,本文内容还是非常重要的!map的应用非常的广泛。今天是回所的第二天,感觉还不错,希望明天和老师的谈话一切顺利。

正文开始分割线---------------------------------------

所谓双列集合,其实就类似于python里的字典,就是一些键值对,其中键不能重复,值可以重复

一、Map集合

基础方法

方法名 说明
V put(K key,V value) 添加元素
V remove(Object key) 根据键删除键值对元素
void clear() 移除所有的键值对元素
boolean containsKey(Object key) 判断集合是否包含指定的键
boolean containsValue(Object value) 判断集合是否包含指定的值
boolean isEmpty() 判断集合是否为空
int size() 集合的长度,也就是集合中键值对的个数
V get(Object key) 根据键获取值
Set keySet() 获取所有键的集合
Collection values() 获取所有值的集合
Set<Map.Entry<K,V>> entrySet() 获取所有键值对对象的集合

Map集合的遍历

这里以键值对对象所组成的单列集合为例给出老三样遍历(又想到了南昌的老三样呜呜~)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("apple", "苹果");
map.put("banana", "香蕉");
map.put("cherry", "樱桃");

Set<Map.Entry<String, String>> entries = map.entrySet();
// 1. 增强for
for (Map.Entry<String, String> entry : entries) {
System.out.println(entry.getKey() + " : " + entry.getValue());
}

// 2. 迭代器
Iterator<Map.Entry<String, String>> it = entries.iterator();
while(it.hasNext()){
System.out.println(it.next());
}


// 3. lambda
entries.forEach(x -> {
System.out.println(x.getKey() + " : " + x.getValue());
});
}

二、HashMap

方法同Map

  • HashMapMap里面的一个实现类
  • 其特点都是由键决定的:无序、不重复、无索引
  • HashMapHashSet底层原理一样,都是哈希表结构

三、LinkedHashMap

由键决定:有序、不重复、无索引

这里的有序指的是保证存储的取出的元素顺序一致

原理:底层数据结构依然是哈希表,知识每个键值对元素有额外的多了一个双链表的机制记录存储顺序

基本与LinkedHashSet类似

image-20240717143345479


四、TreeMap

  • TreeMap和TreeSet底层原理一样,都是红黑树结构
  • 由键决定特性:不重复、无索引、可排序
  • 可排序:对键进行排序
  • 注意:默认按照键的从小到大进行排序,也可以自己规定键的排序规则

如何书写排序:

  1. 实现Comparable接口,指定比较规则 (用得少)
  2. 创建集合时传递Comparator比较器对象,指定比较规则 (用的多,Lambda更简洁)

下面给出这两种写法的示例:

场景:有一个Student类,包含两个私有成员,姓名:String,年龄:Age;每个学生作为键,籍贯作为值;请按年龄升序,如果年龄一样则按照姓名首字母升序

写法一:实现Comparable接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Student类
import java.util.Collection;
import java.util.Comparator;
import java.util.Objects;

public class Student implements Comparable<Student> {
private String name;
private int age;

... javabean内容省略

@Override
public int compareTo(Student o) {
if (o.getAge() != this.getAge()) return this.getAge() - o.getAge();
return this.getName().compareTo(o.getName());
}
}

写法二:传递Comparator比较器对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// main函数
import java.util.*;

public class Test {
public static void main(String[] args) {
TreeMap<Student, String> map = new TreeMap<>((o1, o2) -> {
if(o1.getAge() != o2.getAge()) return o1.getAge() - o2.getAge();
return o1.getName().compareTo(o2.getName());
});
Student s1 = new Student("zhangsan", 18);
Student s2 = new Student("lisi", 18);
Student s3 = new Student("wangwu", 20);

map.put(s1, "北京");
map.put(s2, "天津");
map.put(s3, "石家庄");

System.out.println(map);

}
}