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 map = new HashMap(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 map = new HashMap(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 map = new HashMap(13);
        map.put("a",1);
        map.put("b",2);
        map.put("c",3);
        map.put("d",4);
        map.put(null,null);

        //遍历操作
        Set keys = map.keySet();
        for(String key:keys){
            System.out.println(key+"="+map.get(key));
        }

        //只能获取对应的value值,不能根据value来获取key
        Collection values = map.values();
        for (Integer i:values){
            System.out.println(i);
        }

        //迭代器
        Set keys2 = map.keySet();
        Iterator 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 map = new HashMap(13);
        map.put("a",1);
        map.put("b",2);
        map.put("c",3);
        map.put("d",4);
        map.put(null,null);

        //Map.entry
        Set> entries = map.entrySet(); // Map.Entry是一个接口也有一个泛型, Set也有泛型,就是泛型里套了一个泛型
        Iterator> iterator1 = entries.iterator();
        while (iterator1.hasNext()){
            Map.Entry 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的时候就开始扩容

发生的