HashCode对象排序
目录
1.什么是HashCode(简述哈希表)
哈希表是底层很常用的一种结构,它可以弥补数组的一些不足之处。举个简单的例子: 假设我有10000张卡片,分别放在10000个盒子里面;现在,我想要找出任意一张我想要的卡片,对于数组来说,那我们就得一个盒子一个盒子地遍历,最坏要遍历10000次才能找到。而对于哈希表来说,虽然本质也可以认为是一个数组,但它有一个计算hashcode的hashcode()方法。hashcode()方法是根据一个元素的一些属性,来计算出一个值,可以通过这个值来直接找出元素所在的位置,就像直接用数组下标查询一样。同样是上面卡片的例子: 假如我想要的卡片是红色、菱形、卡面上有3颗星星和一个月亮的图案,我通过hashcode()方法将这几个属性带入进行计算,得到了这张卡片的hashcode值是6200,在没有hash冲突(后面讲) 的情况下,我可以直接找到第6200盒子里就是我想要的卡片,这比数组一个个遍历,快的多得多!
那么我们也可以大概猜到哈希表的建立方式了。对于每一个元素,我们用hashcode()方法带入这个元素的属性进行计算得到hashcode值,也就是常说的hash key,然后把它放到对应的“盒子”里面;想要找到这个元素,只需要重新计算hashcode,然后到对应的“盒子”里去取即可。
自然,我们会面临一种特殊的情况,如果两个属性不同的元素,计算出的hashcode相同怎么办?其实这就是hash冲突。 理想情况下,我们认为hash函数(hash函数就是hashcode()方法)设计的非常好,对于任意两个属性不同的元素,我们计算出的hashcode都不一样,这样,每一个“盒子”里都只有一个元素。但实际情况是,hash冲突一般不容易避免,那么我们碰到hash冲突的情况就会使用单链表的结构连接在原有的元素后。举个例子:如果两张卡片A、B计算出的hashcode值都为6200,卡片A先在“盒子”6200中,那么后来的卡片B就会用链表的形式放在卡片A后面:盒子6200->卡片A->卡片B。
了解了hash冲突,我们再次回到原来的卡片问题。如果哈希表发生了hash冲突,我们要快速找到想要的卡片:我们首先计算卡片的hashcode,然后找到他存储的“盒子”,再使用equals()方法对盒子里所有元素一个个比较即可。举个例子,假设盒子60存在关系:盒子60->卡片A->卡片B->卡片C,我们要找卡片C,首先计算卡片C的hashcode值为60,然后使用对象卡片C的equals()方法,来对盒子60里的元素一个个比较,就可以找到。这样也比数组一个个遍历快得多!
2.常见数据类型的hashCode()方法
2.1 整型Integer类
public class TestHashCode {
public static void main (String[] args) {
Integer ix = 1023;//装箱
System.out.println (ix.hashCode());
}
}
(不知道装箱的小伙伴可以去看link.)
- 输出结果:1023
看了下Integer类的hashCode()方法,发现直接返回的就是储存的整型的值。
2.2 Object类
public class TestHashCode {
public static void main (String[] args) {
Object obj = new Object();
System.out.println (obj);
System