18、集合框架_HashMap\TreeMap
一、什么是Map
▪ Map
– 特点key-value映射
▪ HashMap
– Key无序 唯一(Set)
– Value无序 不唯一(Collection)
▪ LinkedHashMap
– 有序的HashMap 速度快
▪ TreeMap
– 有序 速度没有hash快
▪ 问题:Set与Map有关系吗?
– 采用了相同的数据结构,只用于map的key存储数据,以上是Set
/** * map存储的是k-v键值对映射的数据 * 实现子类: * HashMap:数组+链表(1.7) 数组+链表+红黑树(1.8) * LinkedHashMap:链表 * TreeMap:红黑树 */
1、基本api操作
/* * 增加: * put(k,v) 添加元素 * 查找: * isEmpty 判断是否为空 * size 返回map的大小 * containsKey * containsValue * get * 删除: * clear 清空集合中的所有元素 * remove:删除指定元素 */
public class MapDemo { public static void main(String[] args) { Map<String,Integer> map = new HashMap<String,Integer>(13); map.put("a",1); map.put("b",2); map.put("c",3); map.put("d",4); map.put(null,null); System.out.println(map); } }
打印结果为:
/* {null=null, a=1, b=2, c=3, d=4} Process finished with exit code 0 */
public class MapDemo { public static void main(String[] args) { Map<String,Integer> map = new HashMap<String,Integer>(13); map.put("a",1); map.put("b",2); map.put("c",3); map.put("d",4); map.put(null,null); System.out.println(map); System.out.println(map.isEmpty()); System.out.println(map.size()); // map.clear(); System.out.println(map.containsKey("a")); System.out.println(map.containsValue(2)); System.out.println(map.get("a")); map.remove("a"); System.out.println(map); } }
打印结果为:
/* {null=null, a=1, b=2, c=3, d=4} false 5 true true 1 {null=null, b=2, c=3, d=4} Process finished with exit code 0 */
2、遍历操作
public class MapDemo { public static void main(String[] args) { Map<String,Integer> map = new HashMap<String,Integer>(13); map.put("a",1); map.put("b",2); map.put("c",3); map.put("d",4); map.put(null,null); //遍历操作 Set<String> keys = map.keySet(); for(String key:keys){ System.out.println(key+"="+map.get(key)); } //只能获取对应的value值,不能根据value来获取key Collection<Integer> values = map.values(); for (Integer i:values){ System.out.println(i); } //迭代器 Set<String> keys2 = map.keySet(); Iterator<String> iterator = keys2.iterator(); while(iterator.hasNext()){ String key = iterator.next(); System.out.println(key+"="+map.get(key)); } } }
打印结果为:
/* null=null a=1 b=2 c=3 d=4 null 1 2 3 4 null=null a=1 b=2 c=3 d=4 Process finished with exit code 0 */
entry()
Map.entry:表示的是K-V组合的一组映射关系,key和value成组出现
public class MapDemo { public static void main(String[] args) { Map<String,Integer> map = new HashMap<String,Integer>(13); map.put("a",1); map.put("b",2); map.put("c",3); map.put("d",4); map.put(null,null); //Map.entry Set<Map.Entry<String, Integer>> entries = map.entrySet(); // Map.Entry是一个接口也有一个泛型, Set也有泛型,就是泛型里套了一个泛型 Iterator<Map.Entry<String, Integer>> iterator1 = entries.iterator(); while (iterator1.hasNext()){ Map.Entry<String, Integer> next = iterator1.next(); System.out.println(next.getKey()+"--"+next.getValue()); } } }
打印结果为:
/* null--null a--1 b--2 c--3 d--4 Process finished with exit code 0 */
二、Map下的子类
HashMap和Hashtable怎么选择,有什么不一样
/* * 1、hashmap线程不安全,效率比较高,hashtable线程安全,效率低 * 2、hashmap中key和value都可以为空,hashtable不允许为空 */
三、源码分析
1、jdk1.7
数据结构:数组+链表
1、static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
我们new HashMap时,没有指定长度,其实是可以传的, 如果没有传参就是 16
MUST be a power of two.
必须是2的n次幂
HashMap为什么是16?
算法导论说要是质数, Hashtable 初始化容量是11,是质数
2、static final int MAXIMUM_CAPACITY = 1 << 30;
static final int MAXIMUM_CAPACITY = 1 << 30;
最大容量
3、static final float DEFAULT_LOAD_FACTOR = 0.75f;
默认加载因子,扩容的时候用到
第一次 16*0.75=12 到12的时候就开始扩容
第二次 32*0.75=24 到24的时候就开始扩容
发生的