public class HashCodeDission {
public static void main(String[] args) {
Integer integer = new Integer(10);
Integer integer1 = new Integer("10");
System.out.println(integer.hashCode());
System.out.println(integer1.hashCode());
System.out.println(integer.hashCode()==integer1.hashCode()); // true
System.out.println(integer.equals(integer1)); // true
System.out.println(integer==integer1); //false HashCode值相同的对象不一定相同
/**
* HashCode值相同的对象不一定相同
* 同一个对象的HashCode值一定相同
* equals方法如果不重写,判断的就是==对象是否相同(==对于引用数据类型判断的是内存地址)
* 重写的equals有String,Integer,包装类,此时,equals方法不能再判定为同一个对象
* 一般而言,重写equals的时候要重写HashCode方法,保证equals相同的时候有相同的HashCode值(这一点在Map集合里边非常重要!!!)
* set,map集合底层存储数据时候都是走的map函数底层,判断是否添加的(集合认为不重复,可以加入)的重要规则!
*if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) 为true就判断为重复元素
* 两个条件: 1. 两个对象的hash值相同
* 2. 内存地址相同或者equals方法判断相同 (加入equals判断主要是为了方便重写equals的需求)
* 解读:如果是同一个对象(内存地址相同的那种),hashCode相同,那hash值肯定是相同的,if完为true,判断为重复
* :如果想要要求equals重写后判断为重复元素,还得要求两个对象的hash值一样,就得保证HashCode一样,这样与一下,if完两个true就判断为重复了
* 那么怎么保证呢?只有在重写equals方法时候也重写下Hashcode方法,使得equals判定相同的时候HashCode也相同
* 否则,如果你equals判断相同,但是你的HashCode值不同,你的hash也不同,那么对应的tab表的索引也不同,
* 那么这两个对象(被equals判断为相同的对象)就会被存入不同的tab索引位置,就实现重复元素存入了,和初衷不符合。
*
* (我们可以来验证一下,String方法重写的时候有没有重写HashCode方法)
* 这就是为什么,虽然new String("DH") 和 String name = "DH" 不是用一个对象(内存地址不同)反而不能重复加入集合里,equals相同,且hashcode相同
* 直接被if判断为重复元素了!!!
* */
String name = "dh"; // name指向常量池
String s = new String("dh"); // s 指向堆空间有个value字符串数组,指向常量池
System.out.println(name == s); // false 这两个肯定不是同一个对象
System.out.println(name.equals(s)); // true (重写equals方法判断内容相同)
System.out.println(name.hashCode()==s.hashCode()); // 果然,这里的hasnCode也相同,说明hashCode也重写了!!!
/**总之,就是保证重写equals时候也重写hashCode 保证equals判断相同的时候hashCode也相同,有利于集合的存储*/
}
}
Java中set,map集合如何判断加入对象是否是重复对象
最新推荐文章于 2024-07-08 02:53:27 发布