Java-Map 及其实现类
之前我们用两篇博文一起学习了 单值存储结构,接下来我们将开启 双值存储结构的大门:Map.本文主要以HashMap为例展示代码,其他实现类 方法 与HashMap方法一样,可自行尝试!
Map
补充:Object.hashCode
- 返回对象的哈希码值,支持此方法的有点事散列表,例如 HashMap 提供的散列表
- 由 对象数组 + 链表 组成;对象数组 默认长度是16
- hash算法讲解:通过计算hash值 % 16 产生余数; 该对象存放的位置就是 该余数显示的大小;当某个位置有多个元素存放的时候, 该位置存放的是链表,依次往后放
- JDK1.8的优化:当数组的某个位置的链表长度 (哈系统中的数据量) >8时,链表自动转化成红黑树
- 当 哈希桶中的数据量 减少到 6 时,从红黑树 转化成链表
- 初始桶的数量 16 ; 散列因子 0.75 (当有75% 的桶有数据了,则对数组进行扩容,变为原长度的2倍)
HashMap
-
负载因子:存储数据的长度/创建hashmap的长度
-
size超过了 总容量 * 负载因子,则会扩容。默认情况下,16 * 0.75 = 12个
-
1.初始的容量小,但是存储的数据很多 会频繁散列(往链表中添加数据)
-
2.负载因子过小的话 会占用大量的内存空间(举例:0.5 和 0.75 都有100个长度的数组,但是0.5的话,只能有 50个位置能使用,浪费空间;如果0.75的话,可以有75个位置存放。)
-
为什么 负载因子 不是1,看上去都用了不好嘛?可参照:https://mp.weixin.qq.com/s/_zbOHbQa2zDVosXUlYUrSQ
/**
* Map集合存储的是一个个 键值对数据
* 键不可重复
* set集合只是使用map集合的键
* Map 的任何实现类都可以实现下列操作
*
* Map
* HashMap(线程不安全)/ Hashtable(线程安全)/ConcurrentHashMap(分段锁机制)
* TreeMap
* LinkedHashMap
*/
public class TextMap {
public static void main(String[] args){
HashMap <String,String> data = new HashMap<>() ;
data.put("key1","锄禾日当午");
data.put("key2","汗滴禾下土");
String value = data.get("key1");
System.out.println(value);
value = data.get("key2");
System.out.println(value);
Set<String> set = data.keySet(); // 得到key的单值集合
for (String key:set) {
System.out.println(key+" : "+data.get(key));
}
System.out.println("_________________");
Collection <String> values = data.values();
for(String myvalue: values){
System.out.println(myvalue);
}
}
JDK 9 提供的新特性
-
提供了几个固定长度 的集合 的 更便捷方法
public static void main(String[] args) { List<String> list = List.of("锄禾日当午","汗滴禾下土"); // list.add("谁知盘中餐");//不能使用 for(String s:list){ System.out.println(s); } Set <String> set = Set.of("1111","22222222"); for(String se:set){ System.out.println(se); } Map<String,String> map = Map.of("key1","1111","key2","222"); Set<String> keySet = map.keySet(); for(String key:keySet){ System.out.println(key +":"+map.get(key)); } }s