JAVA基础03-Map

  • Map接口
  • 1.HashMap实现类
  • 1.1 HashMap的参数
  • 1.2 HashMap底层实现
  • 1.3 HashMap扩容机制
  • 1.4 HashMap特点
  • 1.5 HashMap的三种遍历方式
  • 1.5.1 遍历HashMap的entrySet键值对集合
  • 1.5.2 遍历HashMap键的Set集合获取值
  • 1.5.3 遍历HashMap“值”的集合
  • 2 线程安全的 hashmap
  • 2.1 hashtable
  • 2.2 Collections.synchronizedMap
  • 2.3 ConcurrentHashMap
  • 3 其他 Map
  • 3.1 TreeMap
  • 3.2 LinkedHashMap


Map接口

  1. 数据都是键值对,K V同时指定
  2. K不能重复,只能对应一个V

1.HashMap实现类

1.1 HashMap的参数

HashMap 有两个参数影响其性能:初始容量 和加载因子。

  1. 容量 是哈希表中桶的数量,初始容量只是哈希表在创建时的容量,默认初始长度 16。
  2. 加载因子 是哈希表在其容量自动增加之前可以达到多满的一种尺度,默认0.75。

1.2 HashMap底层实现

  1. 内部使用 Entry[] 数组存放数据,数组默认初始长度 16
  2. 调用 key.hashCode() 方法获得一个哈希值
  3. 用哈希值和数组长度取模,hash(key)%n计算下标 i
  4. 键值对要封装成 Entry 对象
  5. Entry 对象放入 i 位置
    5.1 空位置,直接放入
    5.2 有数据,也就是发生hash冲突的时候,依次用 equals() 比较是否相等
    5.2.1 找到相等的,替换值
    5.2.2 没有相等的,链表连接在一起,新加入的节点会从头结点加入

1.3 HashMap扩容机制

  • 负载率、加载因子 到 0.75,数据量/数组容量 到 0.75
  • 新建容量翻倍的新数组
  • 所有数据,重新执行哈希运算,放入新数组
  • jdk1.8
    4.1 链表长度到8,会转成红黑树
    4.2 树上数据减少到6,会转回成链表

1.4 HashMap特点

  • 数据无序
  • 非线程安全
  • 允许key/value为null,但是key只能有一个null

1.5 HashMap的三种遍历方式

1.5.1 遍历HashMap的entrySet键值对集合

  1. 通过HashMap.entrySet()得到键值对集合;
  2. 通过迭代器Iterator遍历键值对集合得到key值和value值;
Iterator it = map.entrySet().iterator();
while (it.hasNext()) {
	Map.Entry entry =it.next();
	key =  entry.getKey();
	value =  entry.getValue();
	System.out.println("key:" + key  + "value:" + value);
}

1.5.2 遍历HashMap键的Set集合获取值

  1. 通过HashMap.keySet()获得键的Set集合;
  2. 遍历键的Set集合获取值;
Iterator it = map.keySet().iterator();
while (it.hasNext()) {
	key =  it.next();
	value =  map.get(key);
	System.out.println("key:" + key + "value:" + value);
}

1.5.3 遍历HashMap“值”的集合

  1. 通过HashMap.values()得到“值”的集合
  2. 遍历“值”的集合
Iterator it = map.values().iterator();
while (it.hasNext()) {
	value = it.next();
	System.out.println("value:" + value);
}

2 线程安全的 hashmap

2.1 hashtable

  • 采用synchronized方法上加锁,使用阻塞同步,效率低。
    不管是读还是写操作,他们都会给整个集合上锁,导致同一时间的其他操作被阻塞

2.2 Collections.synchronizedMap

  • 采用synchronized方法上加锁,使用阻塞同步,效率低
    不管是读还是写操作,他们都会给整个集合上锁,导致同一时间的其他操作被阻塞

2.3 ConcurrentHashMap

  1. 兼顾了线程安全和运行效率
  2. 采用锁分段技术,减小锁的粒度,效率高
    2.1 ConcurrentHashMap中是一次锁住一个桶
    2.2 size()操作时才需要锁住整个hash表

3 其他 Map

3.1 TreeMap

线程安全的,不允许null的键或值;

3.2 LinkedHashMap

对key排好序的Map;
key 就是TreeSet, value对应每个key;