Map接口
Map接口实现类的特点(非常实用)
- Map接口,用于保存具有映射关系的数据,(key——value)
- Map中的key和value可以是任何引用类型的数据,会封装到HashMap$Node对象中
- Map中的key不允许重复,原因与HashSet一样,详情看HashSet源码
- Map中的value可以重复
- Map中的key值可以为null,value也可以为null,注意key为null,只能有一个,value为null可以有多个,
- 常用String类可以作为Map的key
- key和value之间存在一对一的关系,即通过指定的key总能找到对应的value0
package com.JiHe_.Map_;
import java.util.HashMap;
import java.util.Map;
public class Demo01 {
public static void main(String[] args) {
//map接口实现类的特点,使用实现类HashMap来实践
//1.map,用于保存具有映射关系的数据:Key——Value
Map hashMap = new HashMap();
//第一个是key,第二个是值
hashMap.put("no.1","玥");
hashMap.put("no.2","肖");
//注意输出顺序与加入顺序不一致,是因为hash值不同
System.out.println("map="+hashMap);
}
}
-
特点实践
-
package com.JiHe_.Map_; import java.util.HashMap; import java.util.Map; public class Demo01 { public static void main(String[] args) { //map接口实现类的特点,使用实现类HashMap来实践 //1.map,用于保存具有映射关系的数据:Key——Value //2.map的key和value可以是任何引用类型的数据,会封装到HashMap$Node对象中 Map hashMap = new HashMap(); //第一个是key,第二个是值 hashMap.put("no.1","玥"); hashMap.put("no.2","肖"); hashMap.put("no.1","骋");//注意:因为此时hash值一样,所以原value被替换(当有相同的key,就等价于替换) hashMap.put("no.3","骋");//此时因为hash不同,new了一个新的Node,照常输出 hashMap.put(null,null); hashMap.put(null,"666666");//此时key一样,等价于替换 hashMap.put("no.4",null); hashMap.put("no.5",null);//可以理解为id是唯一的,值不是 hashMap.put(1,"甘雨"); hashMap.put(new Object(),"春秋");//k--v //key和value之间存在一对一的关系,即通过指定的key总能找到对应的value System.out.println(hashMap.get("no.5")); System.out.println("map="+hashMap); } }
- Map存放数据的key——value示意图,一对k-v是存放在一个Node中的,又因为Node实现了Entry接口,有些书上也说:一对k-v就是一个Entry
- 注意:实际上真正的key与value实际上是放HashMap$Node里面的,而我们set集合与collection接口只是指向了Node而已,
而set,与collection只是为了方便我们后期遍历。
package com.JiHe_.Map_;
import java.security.KeyStore;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Demo02 {
public static void main(String[] args) {
Map hashMap = new HashMap();
hashMap.put("no.1","玥");
hashMap.put("no.2","肖");
//1. k-v最后是存放在 HashMap$Node node = newNode(hash,key,value,null)
//2. k-v为了方便程序员的遍历,还会创建 EntrySet集合,该集合存放的元素是Entry类型,而Entry对象就有Kay与Value
// EntrySet<Entry<K,V>>
//3.entrySet中,定义的类型是Map.Entry,但是实际存放的还是HashMap$Node
//这是因为HashMap$Node implements Map.Entry
//4. 当把 HashMap$Node对象,存放到entry.Set,就方便了我们的遍历,因为Map.Entry提供了重要的方法
// K getKey();K getValue();
//v为了方便程序员的遍历,还会创建 EntrySet集合
Set set = hashMap.entrySet();
System.out.println(set.getClass());//此时输出的类型是EntrySet(class java.util.HashMap$EntrySet)
for (Object o:set){
//set是Entry类型,所以o本来应该是Entry类型,但是因为HashMap$Node是实现了Entry接口,所以此时是HashMap$Node类型
// System.out.println(o.getClass());
//HashMap$Node类型的对象中取出我们的K与V,
//1.先做一个向下转型
Map.Entry entry=(Map.Entry)o;
//此时o被转化为Entry类型,就可以直接使用Entry接口中的方法,来直接获取K与V
System.out.println(entry.getKey()+" "+entry.getValue());
}
}
}
Node源码
//Map接口中的Node源码,它实现了Map.Entry
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
Node<K,V> next;
Node(int hash, K key, V value, Node<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
理解
真正的key与value实际上是放HashMap$Node里面的,而我们set集合与collection接口只是指向了Node而已,
package com.JiHe_.Map_;
import java.util.*;
public class Demo03 {
public static void main(String[] args) {
HashMap hashMap = new HashMap();
hashMap.put("no1",11);
hashMap.put("no2",12);
//直接输出集合
System.out.println(hashMap);
//遍历
//第一步,将hashMap,使用entrySet()方法,来让set类型的集合指向Map中的Node
Set n1 = hashMap.entrySet();
//System.out.println(n1);//此时n1被转化为set类型的集合
for (Object o:n1){
//再将set类型的n1给到了Object类型的o,我们把o向下转型为Entry类型,然后把o的引用给到s对象,
//此时s就可引用变为Entry的o,就可以使用getKey(),getValue(),的方法来直接获取o的k-v
Map.Entry s = (Map.Entry)o;
System.out.println(s.getKey()+" "+s.getValue());
}
//这就可以看出,他们的编译类型分别是Set与Collection
Set set = hashMap.keySet();
Collection values = hashMap.values();
}
}