第五次总结 初次接触哈希算法
- ArrayList与LinkedList的区别
- Stack与LinkedList的区别
- HashSet与HashMap的区别
- HashMap的实现原理
- TreeMap的实现原理
- 哈希算法
1.ArrayList与LinkedList的区别
1、ArrayList的实现是基于数组,LinkedList的实现是基于双向链表
2、对于随机访问,ArrayList优于LinkedList
3、对于插入和删除操作,LinkedList优于ArrayList
4、LinkedList比ArrayList更占内存,因为LinkedList的节点除了存储数据,还存储了两个引用,一个指向前一个元素,一个指向后一个元素。(可以单向引用)
具体可查看:https://zhuanlan.zhihu.com/p/33141246
2.Stack与LinkedList的区别
- Stack继承自Vector,LinkedList继承自AbstractSequentialList,而AbstractSequentialList继承自AbstractList
- Stack主要用于实现后进先出(LIFO),LinkedList主要用于新增和删除操作
- Stack是线程安全的(Vector是线程安全的),LinkedList不是线程安全的
3.HashSet与HashMap的区别
| HashMap实现了Map接口 | HashSet实现了Set接口 |
| HashMap储存键值对 | HashSet仅仅存储对象 |
| 使用put()方法将元素放入map中 | 使用add()方法将元素放入set中 |
| HashMap中使用键对象来计算hashcode值 | HashSet使用成员对象来计算hashcode值,对于两个对象来说hashcode可能相同,所以equals()方法用来判断对象的相等性,如果两个对象不同的话,那么返回false |
| HashMap比较快,因为是使用唯一的键来获取对象 | HashSet较HashMap来说比较慢 |
4.HashMap的实现原理
1.8以前:HashMap底层是一个长度可变数组+链表
1.8之后:HashMap底层是一个长度可变数组+链表+红黑树
放数据的时候:
1.先判断数组的容量,如果容量不是2的n次方,就向上转为最接近指定容量的最小的2的次方
2.计算Key的hash值
3.根据hash值来计算结点应该放到数组的那个位置
数组长度必须是2的n次方
hash & (数组.length-1) = hash%数组.length
4.计算出下标之后,先看这个位置有没有数据,如果没有,就直接放
如果有数据就比较hash值和key是否相等,如果相等就覆盖掉原来的结点
如果hash值不相等,就将该结点挂在已有结点的尾部
5.如果数组装满了,就要扩容
扩容之后,需要重新计算结点的位置
6.从jdk1.8开始,如果单个下标位置的链表长度超过8,就将该变量转换成一个红黑树
5.TreeMap的实现原理
- 按照key的自然顺序或者执行的比较器来迭代
- TreeMap的底层一个二叉排序树,所有的结点都在二叉树上
- 遍历的时候是按照中序遍历的方式取出所有结点中的元素
6.哈希算法
Java中的每个对象都有一个hashcode方法用来计算对象的哈希值
Java中的每个对象都有一个equals方法来判断对象是否"相等"
equals 比较两个对象是否相等
==是比较两个数据的内存地址是否相同
equals方法是Object的方法,默认和==一样,都是比较地址是否相同
每个类都可以重写equals方法,equals方法是否相等,到底比较什么?取决于是如何重写的??
如果两个equals相等,则hashcode必须相等
如果重写了equals方法,要求要重写hashcode方法
对于equals不一定相等,hashcode不要求不相等,
为了提高程序的效率,通常希望equals不相等的时候,hashcode也不相等
(具体可查看API)

浙公网安备 33010602011771号