Java HashMap底层数据结构:
1.HashMap集合底层是哈希表/散列表的数据结构。
2.哈希表是一种怎么样的数据结构呢?
哈希表是一个数组和单向链表的集合体。
数组:在查询方面效率很高,随机增删方面效率很低。
单向链表:在随机增删方面效率很高,在查询方面效率很低。
哈希表将以上的两种数据结构融合在一起,充分发挥它们各自的优点。
3.HashMap集合底层的源代码:
pubilc class HashMap{
//HashMap底层实际上就是一个数组。(一维数组)
Node<K,V>[] table;
//静态的内部类HashMap.Nade
static class Node<K,V>{
}
}
哈希表/散列表:一维数组,这个数组中每一个元素是一个单向链表。(数组和链表的结合体。)
4.最主要掌握的是:
map.put(k,v)
v=map.get(k)
以上这两种方法的实现原理必须掌握。
package test;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class HashMapTest {
public static void main(String[] args) {
//测试HashMap集合key部分的元素特点
//Integer是key,它hashCode和equals都重新了
Map<Integer,String> map=new HashMap<>();
map.put(111,"zhangsan");
map.put(222,"lisi");
map.put(333,"wangwu");
map.put(444,"sg");
map.put(222,"zhangsan");//key重复的时候value会自动覆盖
System.out.println(map.size());//4
//遍历Map集合
Set<Map.Entry<Integer,String>> set=map.entrySet();
for (Map.Entry<Integer,String> entry:set
) {
System.out.println(entry.getKey()+"="+entry.getValue());
}
}
}
5.结构图:
6.HashMap集合的key部分特点:
无序,不可重复。
为什么无序?因为不一定挂到那个单向链表上。
不可重复是怎么保证的?equals方法来保证HashMap集合的key不可重复。
如果key重复了,value会覆盖。
放在HashMap集合key部分的元素其实就是放在HashSet集合中了。
所以HashSet集合中的元素也需要同时重写hashCode()+equals()方法。
7.哈希表HashMap使用不当时无法发挥性能!
假设将所以的hashCode()方法返回固定为某个值,那么会导致底层哈希表变成了纯单向链表。这种情况我们称为:散列分布不均匀。
假设将所以的hashCode()方法返回值都设定为不一样的值,那么会导致底层哈希表成为以为数组,也是散列分布不均匀。
8.放在HashMap集合key部分的元素,以及放在HashSet集合中的元素需要重写hashCode()和equals()方法
使用IDEA快速生成重写的hashCode()和equals()方法,根据需求选择参数
@Override
public int hashCode() {
return Objects.hash(id, name);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return Objects.equals(id, student.id) &&
Objects.equals(name, student.name);
}
9.HashMap集合的默认初始化容量是16,默认加载因子是0.75
这个默认加载因子是当HashMap集合底层数组容量达到75%的时候,数组开始扩容。
记住:HashMap集合初始化容量必须是2的倍数,这也是官方推荐,这是因为达到散列均匀,为了提高HashMap集合的存取效率,所必须的。
10.HashMap集合底层是哈希表数据结构,是非线性安全的。在JDK8之后,如果哈希表单向链表中元素超过8个,单向链表这种数据结构会变成红黑树数据结构。当红黑树上的节点小于6时,会重新把红黑树变成单向链表数据结构。这种方式也是为了提高检索效率,二叉树的检索会再次缩小扫描范围,提高效率,初始化容量16(既是数组的容量),默认加载因子0.75,扩容为原来的2倍(16*0.75=12 当容量达到12的时候 容量变为16*2=32)。而ArrayList初始容量为10,默认加载因子既为1,扩容为原来的1.5倍+1。