Map双列集合

特点

1、双列集合一次需要存一对数据,分别为键(key)和值(value)
2、键不能重复,值可以重复
3、键和值是一一对应的,每一个键只能找到自己对应的值
4、键+值这个整体我们称之为“键值对”或者“键值对对象”,在Java中叫做“Entry对象”

常见API

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
25
26
 /*
V put(K key V value) 添加元素
V remove(Object key) 根据键删除键值对元素
void clear() 移除所有的键值对元素
boolean containsKey(Object key) 判断集合是否包含指定的键
boolean containsValue(Object value) 判断集合是否包含指定的值
boolean isEmpty() 判断集合是否为空
int size() 集合的长度,也就是集合中键值对的个数
*/


//1、创建Map集合的对象(用多态创建)
Map<String ,String> m = new HashMap<>();

//2、添加元素
//put的方法的细节
//添加+覆盖的功能

//在添加数据的时候,如果键不存在,那么直接把键值对对象添加到map集合当中
//在添加数据的时候,如果键存在,那么就会把原有的键值对对象覆盖,会把被覆盖的值作为返回值返回
m.put("郭靖","黄蓉");
m.put("韦小宝","木健平");

String value = m.put("韦小宝","双儿");
System.out.println(value);//木健平

遍历方式

方式一:键找值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//Map集合的第一种遍历方式

//1、创建Map集合对象
Map<String ,String> m = new HashMap<>();

//2、添加元素
m.put("郭靖","黄蓉");
m.put("韦小宝","木健平");
m.put("欧阳克","黄蓉");

//3、通过键找值

//3.1、获取所有的键,把这些键放到一个单列集合当中
Set<String> keys = map.keySet();
//3.2、遍历每一个集合,得到一个键
for(String key : keys) {
//3.3、利用map集合中的键获取对应的值 get
String value = map.get(key);
System.out.println(key + "=" + value);
}

方式二:键值对遍历

1
2
3
4
5
6
7
8
9
10
11
12
13
14

//上面的12步都一样就不写了
//3、Map集合的第二种遍历方式
//通过键值对对象进行遍历
//3.1、通过一个方法获取所有的键值对对象,返回一个Set集合
Set<Map.Entry<String, String>> entries = map.entrySet();
//3.2、遍历entries这个集合,去得到里面的每一个键值对对象
for(Map.Entry<String, String> entry : entries){
//3.3、利用entry调用get方法获取键和值
String key = entry.getKey();
String value = entry.getValue();
System.out.println(key + "=" + value);
}

方式三:lambda表达式

1
2
3
4
5
//3.利用lambda表达式进行遍历
//底层:
//forEach其实就是利用第二种方式进行遍历,依次得到每一个键和值
//再调用
map.forEach((key, value) -> System.out.println(key + "=" + value));

HashMap

特点

1、HashMap是Map里面的一个实现类。
2、没有额外需要学习的特有方法,直接使用Map里面的方法就可以了。
3、特点都是由键决定的:无序、不重复、无索引,跟值没有任何关系
4、HashMap跟HashSet底层原理是一模一样的,都是哈希表结构,详细请看《HashSet、LinkedHashSet底层》

HashMap底层是哈希表结构的 依赖hashCode方法和equals方法保证键的唯一
*如果键存储的是自定义对象,需要重写hashCode和equals方法
如果值存储自定义对象,不需要重写hashCode和equals方法

LinkedHashMap

特点

1、由键决定:有序、不重复、无索引
2、这里的有序指的是保证存储和取出的元素顺序一致
3、原理:底层数据结构是依然哈希表,只是每个键值对元素又额外的多了一个双链表的机制记录存储的顺序。

TreeMap

特点

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

*代码书写两种排序规则
·实现Comparable接口,只当比较规则
·创建集合时传递Comparator比较器对象,指定比较规则(两种存在时第二种优先)

小练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*
需求:
字符串"aababcabcdabcde"
请统计字符串每一个字符出现的次数,并按照以下格式输出
输出结果:
a(5)b(4)c(3)d(2)e(1)

新的统计思想:利用map集合进行统计

如果题目中没有要求对结果进行排序,默认使用HashMap(效率最高)
如果题目中要求对结果进行排序,请使用TreeMap,因为只有它可以实现自定义排序

键:表示要统计的内容
值:表示次数
*/

//1、定义字符串
String s = "aababcabcdabcde";

//2、创建集合
TreeMap<Character, Integer> tm = new TreeMap<>();

//3、遍历字符串得到里面的每一个字符
for(int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
//拿着c到集合中判断是否存在
//存在,表示当前字符又出现了一次
//不存在。表示当前字符是第一次出现
if(tm.containsKey(c)){
//存在
//先把已经出现的次数拿出来
int count = tm.get(c);
//当前字符又出现了一次
count++;
//把自增之后的结果再添加到集合当中
tm.put(c,count);
}else {
//不存在
tm.put(c,1);
}
}
//4遍历集合,并按照指定的格式进行拼接
//a(5)b(4)c(3)d(2)e(1)
StringBuilder sb =new StringBuilder();

tm.forEach((key, value) -> sb.append(key).append("(").append(value).append(")"));