Map集合详解
Map 是一种键-值对(key-value)集合,Map 集合中的每一个元素都包含一个键对象和一个值对象。其中,键对象不允许重复(hashset),而值对象可以重复(Collection),并且值对象还可以是 Map 类型的,就像数组中的元素还可以是数组一样。
Map 接口主要有两个实现类:HashMap 类和 TreeMap 类。其中,HashMap 类按哈希算法来存取键对象,而 TreeMap 类可以对键对象进行排序。
常用的方法
方法名称 | 说明 |
---|---|
V get(Object key) | 返回 Map 集合中指定键对象所对应的值。V 表示值的数据类型 |
V put(K key, V value) | 向 Map 集合中添加键-值对,返回 key 以前对应的 value,如果没有, 则返回 null |
V remove(Object key) | 从 Map 集合中删除 key 对应的键-值对,返回 key 对应的 value,如 果没有,则返回null |
Set entrySet() | 返回 Map 集合中所有键-值对的 Set 集合,此 Set 集合中元素的数据 类型为 Map.Entry |
Set keySet() | 返回 Map 集合中所有键对象的 Set 集合 |
可以写简单的代码进行测试一下:
Map map=new HashMap();
// 键必须唯一
map.put(1,"tom");
map.put(2,"marry");
map.put(3,false);
map.put(4,new String("admin"));
//map.put(1,"tom2");
//System.out.println(map);
Set keySet = map.keySet();
for(Object o:keySet) {
// System.out.println(o);
// System.out.println("---");
// System.out.println(map.get(o));
}
Collection values = map.values();
Iterator iterator = values.iterator();
Set entrySet = map.entrySet();
for(Object mapping:entrySet) {
Map.Entry entry =(Map.Entry)mapping;
System.out.println(entry.getKey()+"---->"+entry.getValue());
}
在 jdk1.7之后:
new hashMap 之后 系统就帮你创建了一个长度为16的一维数组 Entry【】 table
初次 放 (1,Tom) key ----1 散到了 3号位置 ,添加成功
3,marry key ------------5 号位置,添加成功
假设数据量变多 16个 (哈市算法 — 散列 到3号位置 )如果哈希散列到同一个索引位置,,
equals 判断是否是相同的俩个对象 如果不相同(直接以链表形式存储)
如果哈希值相同(如果发现 put的键 直接跟连上的所有数据keyequals 比较一下,如果发现有相同的key,把此时携带的value 赋值给key所在的entry)它这里是单链。 要注意,它的底层是新值进入,老值在链中。差不多是下面这种情况。
HashMap
HashMap hashmap1=new HashMap();
hashmap1.put("tom1", 12);
hashmap1.put("admin1",13);
hashmap1.put("joker1",14);
System.out.println(hashmap1);
HashMap hashmap2=new HashMap();
hashmap2.put("tom2",21);
hashmap2.put("admin2",31);
hashmap2.put("joker2",41);
//放入操作
hashmap1.putAll(hashmap2);
System.out.println(hashmap1);
//删除操作
hashmap1.remove("tom2");
System.out.println(hashmap1);
//清空操作
// hashmap1.clear();
System.out.println(hashmap1);
//判断是否是空
System.out.println(hashmap1.isEmpty());
hashmap1.put("tom1",120);
System.out.println(hashmap1);
Object object = hashmap1.get("admin1");
System.out.println(object);
//是否包含key值?
boolean containsKey = hashmap1.containsKey("joker1aaaa");
System.out.println(containsKey);
//是否包含value值?
boolean containsValue = hashmap1.containsValue(14567);
System.out.println(containsValue);
除此之外,我们还可使用下面这种算法获得数值和key值,下面这三个只要学会一个,基本就都会了。
// 元视图
//KeySet() Values() entrySet()
// Set entrySet = hashmap1.entrySet();
// Iterator iterator = entrySet.iterator();
// while(iterator.hasNext()) {
// Object next = iterator.next();
// Map.Entry entry= (Map.Entry)next;
// System.out.println(entry.getKey()+"--->"+entry.getValue());
// }
// Set keySet = hashmap1.keySet();
// Iterator iterator = keySet.iterator();
// while(iterator.hasNext()) {
// Object next = iterator.next();
// System.out.println(next+"---->"+hashmap1.get(next));
//
// }
1.7和1.8有很大的不同。
jdk 1.7
new HashMap 还没放数据 16 的 Entry 数组
执行多次put方法之后,
如果下一次有一个key1,value1也落到了key,value这
equals 判断一下,如果相等 ,,替换操作
如果不相等,以链的形式进行存储
7上八下 超过0.7516 进行 扩容162 ----1622
jdk 1.8
new HashMap 底层并没有创建一个长度为16的数组
第一次put数据的时候创建node数组
当一个索引位置上的元素以链表的形式存在的个数大于8,同时扩容之后容量大于64的时候,以数的形式存储(红黑树)
LinedHashMap
这个 HashMap的存储方式 和上次说的HashSet一样,都是使用原来的存储方式,只不过在存储的时候加上了双向链,读取的时候就是按照存入的方式进行读取的。
有两个问题,一是HashMap数据存入LinedHashMap时,输出的结果是怎样的?
另一个就是LinedHashMap数据存入HashMap时,输出结果是怎么样的?
第一种方式:在存入之后读取数据时,数据都或有链。而先输出的就是LinedHashMap中的内容,之后HashMap的内容也是按存入的顺序输出。
第二种呢:就是都变成了HashMap数据,存入的时候是通过hashcode()方法计算存入的,那么读取数据的时候就是从存储单元的头部开始,一直往下读。
TreeMap
之前将了Treeset那么TreeMap很容易理解了。只不过是在放入数据的时候是使用的Map方式。在TreeMap中key不能重复,但是key可以进行排序。所以key的数值类型也必须是一致的。
TreeMap treemap1= new TreeMap();
Student stu1=new Student("admin",14);
Student stu3=new Student("zdmin",16);
Student stu2=new Student("admin",18);
Student stu4=new Student("hdmin",16);
Student stu5=new Student("admin",16);
Student stu6=new Student("fdmin",16);
treemap1.put(stu1, 78);
treemap1.put(stu2, 88);
treemap1.put(stu3, 38);
treemap1.put(stu4, 58);
treemap1.put(stu5, 98);
treemap1.put(stu6, 48);
System.out.println(treemap1);
Hashtable
在这里继续介绍一下Map的实现类Hashtable
这里比较怪,虽然是这么写的名称,但是Hashtable是Map实现类 而且还是线程安全 。所以效率就底点。
这里有区别:与HashMap不同 的是key不能为null,而HashMap key可以为null。
说Hashtable,主要就是使用它的子类properties();这里和i/o流结合起来。后期介绍i/o操作的时候会详细的介绍作用。
这里只是简单的提一下。