一、Map
1.Map集合是以(K-V)键值对的形式存储数据,无序,key可以看为Value的索引,且key是唯一的。
1.1
Map:根接口
* 1.特点
* - 存储的是K-V对
* - 无序
* - key唯一
二、常见实现类:
2.1HashMap:底层使用位桶、链表、红黑树实现(红黑树的加入是jdk1.8后,当链表长度超过阈值(8)时,使用红黑树),大大减少了查找时间
底层 数组、链表、红黑树
2.2TreeMap: 底层位红黑树实现
2.3LinkedHashMap:按插入的顺序排列。HashMap和双向链表合二为一就是LinkedHashMap
2.4Hashtable:和HashMap存储原理相似,但方法都是synchronized,因此时线程安全的
和HashMap的区别为:HashTable线程安全,不常用!
三、常用方法
3.1代码实现
public class TestMapMethod {
public static void main(String[] args) {
//0.创建map对象
HashMap<String, Integer> map = new HashMap<>();
System.out.println(map.size());//0
//1.put
System.out.println("put:");
map.put("java",12);
map.put("c",13);
map.put("jc++",14);
map.put("php",15);
System.out.println(map.put("php",456));
System.out.println(map);
//2.size
System.out.println("size:");
System.out.println(map.size());
//3.isEmpty
System.out.println("isEmpty判断map是否为空:");
System.out.println(map.isEmpty());
//4.containsKey
System.out.println("containsKey:");
System.out.println(map.containsKey("jj"));
System.out.println(map.containsKey("jc++"));
//5.containsValue
System.out.println("containsValue");
System.out.println(map.containsValue(11));
System.out.println(map.containsValue(12));
//6.get
System.out.println("get:");
System.out.println(map.get("java"));
//7.remove
System.out.println("remove:");
System.out.println(map.remove("java"));
//8.putAll
System.out.println("putAll:");
HashMap<String, Integer> map1 = new HashMap<>();
map1.put("python",16);
map1.put("python1",17);
map1.put("python2",18);
map1.put("python3",19);
map.putAll(map1);
System.out.println("putAll(map1)后:"+map);
//9.keyset
System.out.println("keyset:");
System.out.println(map.keySet());
//10.values
System.out.println("values:");
System.out.println(map.values());
//11.forEach
System.out.println("forEach:");
map.forEach(new BiConsumer<String, Integer>() {
@Override
public void accept(String s, Integer integer) {
}
});
System.out.println(map);
//12.remove
System.out.println("remove:");
System.out.println(map.remove("jc++",14));
//13.replace
System.out.println("replace1:");
System.out.println(map.replace("php",15,25));
//14.replace
System.out.println("replace2");
System.out.println(map.replace("php",26));
System.out.println(map);
// //15.compute
// System.out.println("compute:");
// Integer python3 = map.compute("python3", new BiFunction<String, Integer, Integer>() {
// @Override
// public Integer apply(String s, Integer integer) {
// return null;
// }
// });
// System.out.println(map);
// System.out.println(python3);
//entrySet
System.out.println("-------------------");
System.out.println(map);
Set<Map.Entry<String, Integer>> entries = map.entrySet();
for (Map.Entry<String,Integer> entry:entries) {
System.out.println(entry);
System.out.println(entry.getValue());
System.out.println(entry.getKey());
}
}
}
运行结果
0
put:
15
{java=12, c=13, jc++=14, php=456}
size:
4
isEmpty判断map是否为空:
false
containsKey:
false
true
containsValue
false
true
get:
12
remove:
12
putAll:
putAll(map1)后:{python3=19, python2=18, python=16, python1=17, c=13, jc++=14, php=456}
keyset:
[python3, python2, python, python1, c, jc++, php]
values:
[19, 18, 16, 17, 13, 14, 456]
forEach:
{python3=19, python2=18, python=16, python1=17, c=13, jc++=14, php=456}
remove:
true
replace1:
false
replace2
456
{python3=19, python2=18, python=16, python1=17, c=13, php=26}
-------------------
{python3=19, python2=18, python=16, python1=17, c=13, php=26}
python3=19
19
python3
python2=18
18
python2
python=16
16
python
python1=17
17
python1
c=13
13
c
php=26
26
php
四、原理
4.1怎么初始化
1.构造方法中没有做什么任何的数字初始化。
2.负载因子
·默认0.75f
·元素的数量 XX。size /capacity。是一个最优解,为了增加HashMap性能
3.最大容量:默认值为2^30
4.2put的原理
put方法会初始化位桶Node数组的初始大小,默认为16.
建议每个实体类都增加hashCode方法equals方法
-
1.put方法传值时,会先计算key的hashCode方法返回的int值,根据hash算法确定当前元素key在位桶中的位置
-
2.如果该位置无元素,则直接放入数组中。
-
3.如果该位置上有元素,则产生了hash冲突(哈希碰撞)。
-
4.产生hash冲突后,根据key的equals方法判断key是否相等,如果相等,则将key所对应的v覆盖
-
5.如果key的equals方法不相等,则采用尾插法将元素插入链表的尾部。
-
6.当链表长度大于7时,链表转为红黑树进行储存
-
7.当位桶Node数组大于指定容量(指结合负载因子所计算出来的容量)时,扩容。
-
8.扩容为原容量的2倍