Map接口定义了双例集合的存储特征,它并不是Collection接口的子接口。
双例集合的存储特征是以key 与value结构为单位进行存储。体现的是数学中的函数 y=f(x)感念。
Collection中的容器,元素是孤立存在的,向集合中存储元素采用一个全元素的方式存储。
Map中的容器,元素是成对存在的
每个系由键与值两部分组成,通过键可以找对所对应的值。
Collection 中的容器称为单列集合。Map 中的容器称为双列集合。
Map中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。
Map中常用的容器为HashMap,TreeMap 等。
V put(K key,V value)把key与Value添加到Map集合中
特点①如果HashMap容器中存在该key,则新的Value会覆盖原来的Value
特点②在前提为存在被覆盖的元素,put方法返回值为被覆盖的元素,否则返回空
import java.util.HashMap; public class demo { public static void main(String[] args) { HashMap<Integer, Integer> map = new HashMap<>();//实例化hashmap集合 map.put(1,2);//添加元素,<k,v> <1,2> int value=map.put(1,4);//因为key<1,2>和<1,4>key相同,所以4覆盖2,返回值value为2 System.out.println(value);//返回值value为2 } }
V get(Object key)根据指定的key,获取对应的value
这个方法存在劣势:如果不提前知道容器中key的值,不能取对应value
优势在于已知key取对应元素
import java.util.HashMap; public class demo { public static void main(String[] args) { HashMap<Integer, Integer> map = new HashMap<>(); System.out.println("-------1.添加元素--------"); map.put(1,2); int value=map.put(1,4); System.out.println(value); System.out.println("------2.获取元素--------"); Integer get1 = map.get(1); System.out.println(get1); } }
Set keyset()获取Map集合中所有的key,存储到set集合中
import java.util.HashMap; import java.util.Set; public class demo { public static void main(String[] args) { HashMap<Integer, Integer> map = new HashMap<>(); System.out.println("-------1.添加元素--------"); map.put(1,2); int value=map.put(1,4); System.out.println(value); System.out.println("------2.获取元素--------"); Integer get1 = map.get(1); System.out.println(get1); System.out.println("-------3.第二种获取元素方法-----"); map.put(2,4);//为了效果,多添加几个元素 map.put(4,6); map.put(6,8); Set<Integer> keys = map.keySet();//keyset方法获取所有key,因为set集合,所以用强化for for (Integer key : keys) {//循环遍历 System.out.println(key+"---"+map.get(key));//key拼接上get方法得到每个key的value } } }
通过set<Map.Entry<k,v>> entrySet()返回一个set基于Map,Entry类型包含Map中所有映射
import java.util.HashMap; import java.util.Map; import java.util.Set; public class demo02 { public static void main(String[] args) { HashMap<String, String> map = new HashMap<>(); System.out.println("-----第三种方式-----"); map.put("a","A"); map.put("b","B"); map.put("c","C"); map.put("d","D"); map.put("e","E"); map.put("f","F"); Set<Map.Entry<String, String>> entries = map.entrySet(); for (Map.Entry<String, String> entry : entries) { String K=entry.getKey(); String V = entry.getValue(); System.out.println(K+"---------"+V); } } }
void putAll(Map m)从指定Map中将所有映射关系复制到此Map中
劣势:两个数据类型要一致
特点,当被两哥map都有相同的key,被复制的map会覆盖到当前map的相同key的value
import java.util.HashMap; import java.util.Map; import java.util.Set; public class demo03并集 { public static void main(String[] args) { HashMap<String, String> map = new HashMap<>(); map.put("a","A"); map.put("b","B"); map.put("c","C"); map.put("d","D"); map.put("e","E"); map.put("f","F"); HashMap<String, String> map2 = new HashMap<>(); map2.put("A","a"); map2.put("B","b"); map2.put("C","c"); map2.put("D","d"); map2.put("E","e"); map2.put("F","f"); map2.putAll(map);//将map中的映射关系复制到map2中 Set<Map.Entry<String, String>> entries = map2.entrySet(); for (Map.Entry<String, String> entry : entries) { System.out.println("key"+entry.getKey()+"----------"+"value"+entry.getValue()); } } }
import java.util.HashMap; import java.util.Map; import java.util.Set; public class demo02 { public static void main(String[] args) { HashMap<String, String> map = new HashMap<>(); map.put("a","A"); map.put("b","B"); map.put("c","C"); map.put("d","D"); map.put("e","E"); map.put("f","F"); map.remove("f");//删除key为f对应的映射值 Set<Map.Entry<String, String>> entries = map.entrySet(); for (Map.Entry<String, String> entry : entries) { String K=entry.getKey(); String V = entry.getValue(); System.out.println(K+"---------"+V); } } }
package day18.map; import java.util.HashMap; import java.util.Map; import java.util.Set; public class demo02 { public static void main(String[] args) { HashMap<String, String> map = new HashMap<>(); map.put("a","A"); map.put("b","B"); map.put("c","C"); map.put("d","D"); map.put("e","E"); map.put("f","F"); map.remove("f"); map.clear();//删除所有映射 Set<Map.Entry<String, String>> entries = map.entrySet(); for (Map.Entry<String, String> entry : entries) { String K=entry.getKey(); String V = entry.getValue(); System.out.println(K+"---------"+V); } } }
boolean containsKey(Object key)判断容器中是否有指定的key Boolean containsValue(Object value)判断容器中是否有指定的value import java.util.HashMap; import java.util.Map; import java.util.Set; public class demo02 { public static void main(String[] args) { HashMap<String, String> map = new HashMap<>(); map.put("a","A"); map.put("b","B"); map.put("c","C"); map.put("d","D"); map.put("e","E"); map.put("f","F"); boolean c1 = map.containsKey("a"); boolean c2 = map.containsValue("A"); System.out.println(c1); System.out.println(c2); } }
HashMap底层实现采用了哈希表,这是一种非常重要的数据结构。对于我们以后理解
很多技术都非常有帮助,因此,非常有必要让大家详细的理解。
数据结构中由数组和链表来实现对数据的存储,他们各有特点。
(1)数组:占用空间连续。寻址容易,查询速度快。但是,增加和删除效率非常低。
(2链表:占用空间不连续。寻址困难,查询速度慢。但是,增加和删除效率非常高。
那么,我们能不能结合数组和链表的优点(即查询快,增删效率也高)呢?答案就是
“哈希表”。哈希表的本质就是“数组+链表”。
hashmap1.8版本:
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
表示默认初始容量为16
1左位移4.就是12222=16
指的是上图中数组的初始长度为16
static final int MAXIMUM_CAPACITY = 1 << 30;
数组的最大存储容量为2的30次方
static final float DEFAULT_LOAD_FACTOR = 0.75f;
含义:比如说默认长度为16,16*0.75=12,当数组存储12个元素的时候,数组就要开始进行扩容
static final int TREEIFY_THRESHOLD = 8;
*hold:阈值
含义:就是确定链表在什么情况下要转化为红黑树,值为8
static final int UNTREEIFY_THRESHOLD = 6;
含义:在什么阈值情况下从红黑树转化为链表,值为6
static final int MIN_TREEIFY_CAPACITY = 64;
含义:当数组长度达到64或者超过64,将节点个数为8的链表转化红黑树
transient int size;
含义:计数用的,统计数组中键-值的数量
transient Node<K,V>[] table;
类型是node
含义:前面讲的数组就是这货,table就是这货名字
单向链表的机制
注意:
*ctrl+u跳转到当前类继承关系上一级
图中可以看懂Treenode继承Entry再往下可以看到继承了Node,所以可以得Treenode继承Node
|
|
|
|
|
|
上一章节-java篇-DAY18-集合框架2
下一章节-随缘更新!!!
天天更新不容易,随手点个小赞