此处讲的是JDK8的Map接口
- Map与Collection并列存在,用于保存具有映射关系的数据Key-Value
- Map中的Key和Value可以使任何引用类型的数据,会封装到HashMap<span data-formula="Node对象中
- Map中的key不允许重复,原因和HashSet一样。当有相同的key时,等价于替换,新的value将旧value替换
- Map中的value可以重复
- Map中的key可以为null, value也可以为null, 注意key为null,只能有一个, value为null可以有多个
- 常用String类作为Map的key
- key和value之间存在单向一对一关系,即通过指定的key总能找到对应的Key
- Map存放数据的key-value示意图,一对k-v是放在一个HashMap" aria-hidden="true">Node中的,又因为Node实现了Entry接口,有些书上也说一对k-v就是一个Entry

Map体系继承图

Map接口常用方法
- put添加
- remove根据key删除
- get根据key获取
- size
- isEmpty
- clear
- containsKey
Map遍历方法
- containsKey:查找键是否存在
- keySet:获取所有的键
- entrySet:获取所有关系k-v
- values:获取所有的值

第一组方法:先取出所有的key,通过key取出对应的Value
Set keyset = map.keySet();
//(1)增强for
for(Object key:keyset){
//输出map.get(key)
}
//(2)迭代器
Iterator iterator = keyset.iterator();
while(iterator.hasNext()){
Object key = iterator.next();
//输出map.get(key)
}
第二组方法:取出所有values
map.values()
第三组方法:通过EntrySet,获取k-v
Set entrySet = map.entrySet();
//(1)增强for
for(Object entry: entrySet){
Map.Entry m = (Map.Entry)entry;
//输出m.getKey()和m.getValue()
}
//(2)迭代器
Iterator iterator = entrySet.iterator();
while(iterator.hasNext()){
Object entry = iterator.next();
Map.Entry m = (Map.Entry)entry;
//输出m.getKey()和m.getValue()
}
HashMap小结
- Map接口常用实现类:HashMap, Hashtable和Properties
- HashMap是Map接口使用频率最高的实现类。
- HashMap是以key-val对的方式来存储数据
- key不能重复,但value可以从夫,允许使用null键和null值
- 如果添加相同的key,会覆盖掉原来的key-val,即修改val,key不会替换
- 与HashSet一样,不保证映射顺序,因为底层是以hash表方式存储的
- HashMap没有实现同步,线程不安全
HashMap扩容机制,同HashSet
- HashMap底层维护了Node类型的数据table,默认为null
- 创建对象时,加载因子(loadfactor)初始化为0.75
- 当添加key-val时,通过key的哈希值得到在table的索引。然后判断该索引处是否有元素,如果没有元素直接添加。如果该索引处有元素,继续判断该元素的key是否和准备加入的key相等,如果相等,则直接替换val;如果不相等宣布要判断是树结构还是链表结构,做出对应处理。如添加时发现容量不够,则需要扩容
- 第一次添加,则需要扩容table容量为16,临界值(threshold)为12
- 以后再扩容,则需要扩容table容量为原来两倍,临界值为原来两倍
- java8中,如果一条链表元素超过TREEIFY_THRESHOLD(默认为8), 并且table的大小 >= MIN_TREEIFY_CAPACITY(默认64),就会进行树化(红黑树)
HashTable
- 存放的元素是键值对:k-v
- Hashtable的键和值都不能为null
- Hashtable使用方法基本和HashMap一样
- Hashtable是线程安全的,HashMap是线程不安全的
Hashtable底层
- 底层有数组Hashtable<span data-formula="Entry[], 初始化大小为11
- 临界值threshold 8=11*0.75
- 扩容方法:
当达到临界值,还在添加k-v到Entry中时,按照
int new Capacity = (oldCapacity<<1) +1 扩容,即扩容1倍+1
Hashtable VS HashMap

Properties
- Properties类继承自Hashtable类并实现了Map接口,也是使用键值对的形式来保存数据
- 使用特点与Hashtable类似
- Properties还可以用于从xxx.properties文件中,建在数据到Properties类对象,并进行读取和修改
- 工作后xxx.properties文件常作为配置文件" aria-hidden="true">Entry[], 初始化大小为11
- 临界值threshold 8=11*0.75
- 扩容方法:
当达到临界值,还在添加k-v到Entry中时,按照
int new Capacity = (oldCapacity<<1) +1 扩容,即扩容1倍+1
Hashtable VS HashMap

Properties
- Properties类继承自Hashtable类并实现了Map接口,也是使用键值对的形式来保存数据
- 使用特点与Hashtable类似
- Properties还可以用于从xxx.properties文件中,建在数据到Properties类对象,并进行读取和修改
- 工作后xxx.properties文件常作为配置文件
本文章使用limfx的vscode插件快速发布