Map接口与HashMap

Map接口的特点

  1. Map保存具有映射关系的数据key:value(双列元素)
  2. 其结果还是无序的,其中key与value可以是任意数据的类型
  3. 同时其结果还是无序的,当有相同的key时,就相当于替换
  4. Map与value都可以为空,但是key只能是一个为空,value可以有多个空
  5. 常用String作为key,key常用一对一的关系,一个key对应一个value
  6. Map存放数据的key-value,一个k-v是放在一个Node中,因为Node实现了Entry接口,也可说一对k–v就是一个Entry
  7. 线程不安全的,没有做方法上的同步互斥操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.time.LocalDate;
import java.util.*;

public class Test {
public static void main(String[] args) {
Map map=new HashMap();
map.put("姓名","zhang");
map.put("姓名","zhang");
map.put("年龄",96);
System.out.println(map);
map.put("姓名","王");
map.put(null,"啊");
map.put(null,"moqi");
System.out.println(map);
}
}

image-20220312104437597

k-v后是HashMap$Node,k-v为了方便程序员遍历,还需创建EntrySet集合,该集合存放的数据类型Entry,而一个Entry对象就有k,v,EntrySet<Entry<k,v>>,entrySet中,定义的类型是Map.entry,但是实际上存放的是HashMap$Node,因为他继承了Map.Entry,而继承方便是为了方便遍历,是因为entry提供了getValue与getKey的方法

1
2
3
4
5
6
7
8
9
10
11
import java.time.LocalDate;
import java.util.*;

public class Test {
public static void main(String[] args) {
HashMap hashMap=new HashMap();
hashMap.put("sdv","sav");
hashMap.put("huawei","sd");
hashMap.put(new String("阿会"),new String("鬼"));
}
}

我们debug以上的代码,将table的数组转换成entry中,entry中的值指向了table地址,而同样也有keyset方法可以直接去除其键,而不去除其值。

image-20220312111911202

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
import java.time.LocalDate;
import java.util.*;

public class Test {
public static void main(String[] args) {
Map map=new HashMap();
map.put("奥迪","1256");
//发生替换
map.put("奥迪","4523542543");
map.put("奔驰","45235425");
System.out.println(map);
map.remove("奔驰");
System.out.println(map);
System.out.println(map.get("奥迪"));
System.out.println(map.size());
//查找键是否存在
System.out.println(map.containsKey("奔驰"));
//判断是否为空
System.out.println(map.isEmpty());
//清除键值对的关系
map.clear();
System.out.println(map);
}
}

image-20220312113018419

Map的遍历方法

containsKey:查找键是否存在

keySet:获取所有的键

entrySet:获取所有的关系

values:获取所有发值

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
import java.time.LocalDate;
import java.util.*;

public class Test {
public static void main(String[] args) {
Map map=new HashMap();
map.put("奥迪","1256");
//发生替换
map.put("奔驰","45235425");
map.put("打本","1000");
//遍历方式1
Set keyset=map.keySet();
for (Object key:keyset){
System.out.println(key+"-"+map.get(key));
}
//遍历方式2
Iterator iterator= keyset.iterator();
while (iterator.hasNext()){
Object key=iterator.next();
System.out.println(key+"-"+map.get(key));
}

//遍历方式3
Collection values=map.values();
for (Object key:values){
System.out.println(key);
}


//遍历方式3通过entry来获取k-v
Set entrySet=map.entrySet();
for (Object key:entrySet){
Map.Entry m=(Map.Entry) key;
System.out.println(m.getKey()+"-"+m.getValue());
}
//迭代器求法
Iterator iterator1=entrySet.iterator();
while (iterator1.hasNext()){
Object next=iterator1.next();
//此时
System.out.println(next);
}


}
}

image-20220312134547645

HashMap的底层机制

数组(table)+链表(每一个节点实现了HashMap$Node,同时node接口实现了Map$Entry)

jdk8之后底层实现了数组+链表+红黑树

其底层机制与HashSet相同,因为hashSet底层实现了hashmap,同时树化的条件也相同