精华内容
下载资源
问答
  • 重写equals方法
    千次阅读 多人点赞
    2021-12-18 13:17:42

    Java中的hash值主要是用来在散列存储结构中确定对象的存储地址的,提高对象的查询效率。

    Java设计的顶级父类Object类中,有两个方法很特殊,它们分别是equals方法与hashCode方法。——一旦重写了equals方法,就一定要重写hashCode方法。以下是Object的源码:

    public class Object {
    
     /* 
      * Note that it is generally necessary to override the {@code hashCode}
      * method whenever this method is overridden, so as to maintain the
      * general contract for the {@code hashCode} method, which states
      * that equal objects must have equal hash codes.
      */
      public boolean equals(Object obj) {
        return (this == obj);
      }
    
     /*
      * The general contract of {@code hashCode} is:
      * <ul>
      * <li>Whenever it is invoked on the same object more than once during
      *     an execution of a Java application, the {@code hashCode} method
      *     must consistently return the same integer, provided no information
      *     used in {@code equals} comparisons on the object is modified.
      *     This integer need not remain consistent from one execution of an
      *     application to another execution of the same application.
      * <li>If two objects are equal according to the {@code equals(Object)}
      *     method, then calling the {@code hashCode} method on each of
      *     the two objects must produce the same integer result.
      * <li>It is <em>not</em> required that if two objects are unequal
      *     according to the {@link java.lang.Object#equals(java.lang.Object)}
      *     method, then calling the {@code hashCode} method on each of the
      *     two objects must produce distinct integer results.  However, the
      *     programmer should be aware that producing distinct integer results
      *     for unequal objects may improve the performance of hash tables.
      * </ul>
      * <p>
      * As much as is reasonably practical, the hashCode method defined by
      * class {@code Object} does return distinct integers for distinct
      * objects. (This is typically implemented by converting the internal
      * address of the object into an integer, but this implementation
      * technique is not required by the
      * Java&trade; programming language.)
      *
      */
      public int hashCode() {
        return identityHashCode(this);
      }
    
    
      /* package-private */ static int identityHashCode(Object obj) {
        int lockWord = obj.shadow$_monitor_;
        final int lockWordStateMask = 0xC0000000;  // Top 2 bits.
        final int lockWordStateHash = 0x80000000;  // Top 2 bits are value 2 (kStateHash).
        final int lockWordHashMask = 0x0FFFFFFF;  // Low 28 bits.
        if ((lockWord & lockWordStateMask) == lockWordStateHash) {
          return lockWord & lockWordHashMask;
        }
        return identityHashCodeNative(obj);
      }
    
    
    }
    

    如果一个类没有重写equals(Object obj)方法,则等价于通过==比较两个对象,即比较的是对象在内存中的空间地址是否相等;如果重写了equals(Object obj)方法,则根据重写的方法内容去比较相等,返回true则相等,false则不相等。

    equals方法注释中的大致意思是:当我们将equals方法重写后有必要将hashCode方法也重写,这样做才能保证不违背hashCode方法中“相同对象必须有相同哈希值”的约定。

    hashCode方法本质就是一个哈希函数,Object类的作者在注释的最后一段的括号中写道:将对象的地址值映为integer类型的哈希值。

    提到hashCode,就会想到哈希表,将某一对象的值映射到表中的某个位置,从而达到以O(1)的时间复杂度来查询该对象的值。hashCode是一个native方法,哈希值的计算利用的内存地址。哈希表在一定程度上也可以起到判重的作用,但也可能存储哈希冲突,即使是两个不同的对象,它们的哈希值也可能是相同的。因此,虽然哈希表具有优越的查询性能,但也可能存在哈希冲突。

    hashCode方法注释中列了个列表,列表中有三条注释,当前需要理解的大致意思如下:

    • 一个对象多次调用它的hashCode方法,应当返回相同的integer(哈希值);
    • 两个对象如果通过equals方法判定为相等,那么就应当返回相同integer
    • 两个地址值不相等的对象调用hashCode方法不要求返回不相等的integer,但是要求拥有两个不相等integer的对象必须是不同对象。

    对象与hash值

    图中存在两种独立的情况:

    • 相同的对象必然导致相同的哈希值;
    • 不同的哈希值必然是由不同对象导致的;

    因此,equals方法与hashCode方法根本就是配套使用的。对于任何一个对象,不论是使用继承自Objectequals方法还是重写equals方法。hashCode方法实际上必须要完成的一件事情就是,为该equals方法认定为相同的对象返回相同的哈希值。如果只重写equals方法没有重写hashCode方法,就会导致``equals`认定相同的对象却拥有不同的哈希值。

    Object类中的equals方法区分两个对象的做法是比较地址值,即使用==。如果根据业务需求改写了equals方法的实现,那么也应当同时改写hashCode方法的实现。否则hashCode方法依然返回的是依据Object类中的依据地址值得到的integer哈希值。

    代入到具体的例子 –String类,在String类中,equals方法经过重写,具体实现源码如下:

    public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
    
      public boolean equals(Object anObject) {
        if (this == anObject) {
          return true;
        }
        if (anObject instanceof String) {
          String anotherString = (String) anObject;
          int n = length();
          if (n == anotherString.length()) {
            int i = 0;
            while (n-- != 0) {
              if (charAt(i) != anotherString.charAt(i))
                return false;
              i++;
            }
            return true;
          }
        }
        return false;
      }
    
    }
    

    通过源码可以看到,String对象在调用equals方法比较另一个对象时,除了认定相同地址值的两个对象相等以外,还认定对应着的每个字符都相等的两个String对象也相等,即使这两个String对象的地址值不同(即属于两个对象)。

    String类中对equals方法进行重写扩充了,但是如果此时我们不将hashCode方法也进行重写,那么String类调用的就是来自顶级父类Obejct类中的hashCode方法。即,对于两个字符串对象,使用它们各自的地址值映射为哈希值。 也就是会出现如下情形:

    字符串常量

    也就是说,String类中的equals方法认定为相等的两个对象拥有两个不同的哈希值——因为它们的地址值不同。

    为什么重写equals方法就得重写hashCode方法?—— 因为必须保证重写后的equals方法认定相同的两个对象拥有相同的哈希值。同时我们也得出了——hashCode方法的重写原则就是保证equals方法认定为相同的两个对象拥有相同的哈希值。

    equals里一般比较的比较全面比较复杂,这样效率就比较低,而利用hashCode进行对比,则只要生成一个hash值进行比较就可以了,效率很高,那么既然hashCode效率这么高为什么还要使用equals进行比较呢?

    因为hashCode并不是完全可靠,有时候不同的对象生成的hashcode也会一样(hash冲突),所以hashCode只能说是大部分时候可靠,并不是绝对可靠。 所以可以得出:

    • equals相等的两个对象,它们的hashCode肯定相等,也就是用equals对比是绝对可靠的;
    • hashCode相等的两个对象,它们的equals不一定相等,也就是hashCode不是绝对可靠的;

    所有对于需要大量并且快速的对比的话如果都用equals去做显然效率太低,解决方式是,每当需要对比的时候, hashCode去对比,这就用到了哈希表,能够快速的地位到对象的存储位置,如果hashCode不一样,则表示这两个对象肯定不相等(也就是不必再用equals去再对比了),如果hashCode相同,此时再对比它们的 equals,如果equals也相同,则表示这两个对象是真的相同了。

    查看字符串的hashCode

    String str = new String("abc");
    System.out.println(str.hashCode()); // 96354
    str += "a";
    System.out.println(str.hashCode()); // 2987071
    str += "b";
    System.out.println(str.hashCode()); // 92599299
    String str1 = "abcab";
    System.out.println(str.hashCode() + " " + str1.hashCode()); // 92599299 92599299
    
    String str2 = "ab";
    String str3 = new String("ab");
    System.out.println(str2.hashCode() + " " + str3.hashCode()); // 3105 3105
    

    以下是String.hashCode的源码:

    public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
      
      private int hash; // Default to 0
      
       /**
         * Returns a hash code for this string. The hash code for a
         * {@code String} object is computed as
         * <blockquote><pre>
         * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
         * </pre></blockquote>
         * using {@code int} arithmetic, where {@code s[i]} is the
         * <i>i</i>th character of the string, {@code n} is the length of
         * the string, and {@code ^} indicates exponentiation.
         * (The hash value of the empty string is zero.)
         *
         * @return  a hash code value for this object.
         */
        public int hashCode() {
            int h = hash;
            if (h == 0 && value.length > 0) {
                char val[] = value;
    
                for (int i = 0; i < value.length; i++) {
                    h = 31 * h + val[i];
                }
                hash = h;
            }
            return h;
        }
    
    }
    

    由上面的代码可知,String类的hashCode的值为s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1],其中s是字符串对应的char数组,所以字符串内容一样的String对象,调用hasCode()返回值是一样的。但是反过来,当hashCode返回的值一样时,其字符串内容不一定一样,因为上面的方法计算hash时可能会发生位数溢出。

    参考

    https://zhuanlan.zhihu.com/p/50206657
    https://blog.csdn.net/weixin_64735186/article/details/122727751

    更多相关内容
  • 重写equals方法

    千次阅读 2022-05-05 17:09:07
    重写equals方法 总结 我们在java程序中调用自带的equals方法时,你是否会有这样的疑问:明明我比较的数据都一样啊,为什么会返回false呢?有些人可能还会疑问,怎么有时候返回true?有时候返回false呢?这是为什么...

    目录

    equals()方法是做什么的?

    实战场景

    contains底层逻辑判断

    内存图

    重写equals方法

    总结


    我们在java程序中调用自带的equals方法时,你是否会有这样的疑问:明明我比较的数据都一样啊,为什么会返回false呢?有些人可能还会疑问,怎么有时候返回true?有时候返回false呢?这是为什么呢?其实是和Java底层人家写的equals方法逻辑有关系

    equals()方法是做什么的?

    英语角度:

    计算机角度:比较多个值是否相等

    实战场景

    先来看段代码我们脑海中有个场景吧!

    User类

    package StringEquals;
    
    public class User {
        private String name;
    
        public User() {
        }
    
        public User(String name) {
            this.name = name;
        }
    }

    主函数

    package StringEquals;
    import java.util.ArrayList;
    import java.util.Collection;
    
    public class Main {
        public static void main(String[] args) {
            //实例化一个集合对象
            Collection c = new ArrayList();
            
            //实例化一个叫唐三的对象
            User tangsan1 = new User("唐三");
            
            //再次实例化一个叫唐三的对象
            User tangsan2 = new User("唐三");
            
            //把第一个tangsan1对象添加到集合中
            c.add(tangsan1);
            
            //判断集合中是否包含叫唐三的对象
            System.out.println(c.contains(tangsan2)); 
        }
    }

    客户端输出结果

    此时是不是就疑惑了,明明tangsan1和tangsan2这两个变量所指向的对象都叫唐三啊,集合中也有叫唐三的这个对象,那为什么在判断集合是否包含叫唐三的对象时返回false呢?这是为什么? 我们先来看看Java中底层定义的contains方法是如何进行逻辑判断的,如下图。

    contains底层逻辑判断

    通过进入到contains方法底层,发现在进行逻辑判断的时候会调用equals方法进行比较。我们通过debug单步调试进入到equals底层之后发现,如下图:

    this==obj,这里实际上比较的是tangsan1和tangsan2这两个对象的内存地址,因为实例化时分别new了两个不同的User对象,所有tangsan1和tangsan2这两个变量实际上所存储的地址空间不同、指向的对象也不同。

    内存图

    我们在来画一张这个程序的内存图,看看每一个变量和对象再内存中是如何划分的,如下图:

    看出来有什么不同了吗?虽然在代码中tangsan1和tangsan2这两个变量所指向的对象都叫唐三,但是他们分别所指向的对象不同,这两个对象所指向的地址也不同。


    重写equals方法

    有些人可能就问了,我只想判断两个对象里面的数据是否相同,如何做?重写equals方法,代码如下:

    User类

    package StringEquals;
    
    public class User {
        private String name;
    
        public User() {
        }
    
        public User(String name) {
            this.name = name;
        }
    
        //重写equals方法,比较连个对象里面的数据是否一致
        public boolean equals(Object o) {
            if (o == null || !(o instanceof User)) return false;
            if (o == this) return true;
            User u = (User) o;
            return u.name.equals(this.name);
        }
    }

    主函数

    package StringEquals;
    import java.util.ArrayList;
    import java.util.Collection;
    
    public class Main {
        public static void main(String[] args) {
            //实例化一个集合对象
            Collection c = new ArrayList();
            
            //实例化一个叫唐三的对象
            User tangsan1 = new User("唐三");
            
            //再次实例化一个叫唐三的对象
            User tangsan2 = new User("唐三");
            
            //把第一个tangsan1对象添加到集合中
            c.add(tangsan1);
            
            //判断集合中是否包含叫唐三的对象
            System.out.println(c.contains(tangsan2)); 
        }
    }

    客户端输出结果

    这里我们重写了equals方法,之后在调用equals方法的时候,程序就会调用我们自己写的这个重写之后的equals方法,程序就会认为tangsan1也叫唐三,tangsan2也叫唐三,他们名字相同就是同一个人。

    总结

    • 不重写:调用Objcet的equals方法,判断的是内存地址是否一致
    • 重写:调用自定义的equals方法,判断是内容是否一致
    • 存放在一个集合中的类型,一定要重写equals方法

    展开全文
  • 【Java基础】重写equals方法详讲

    千次阅读 2022-05-08 19:30:23
    重写equals方法 【Java比较学习】重写equals方法的安全写法 重写equals方法的两种方式 这里提供两个比较常见的equals重写方法: ● 用instanceof实现重写equals方法 ● 用getClass实现重写equals方法 先说结论,...

    一、重写equals方法

    【Java比较学习】重写equals方法的安全写法

    1、重写equals方法的两种方式

    这里提供两个比较常见的equals重写方法:
    ● 用instanceof实现重写equals方法
    ● 用getClass实现重写equals方法

    先说结论,getClass()比instanceof更安全。接下来就是我们自己要来实现equals方法了。

    2、场景描述

    假设有此场景:
    在已经创建好的长方形类中重写Object类中的equals方法为当长方形的长和宽相等时,返回TRUE,同时重写hashCode方法,重写toString方法为显示长方形的长宽信息。并测试类。

    package com.test10_04;
    
    import java.util.Objects;
    
    class Rectangle {
        private double length;
        private double wide;
    
        public Rectangle() {
            //空实现
        }
        public Rectangle(double length, double wide) {
            setLength(length);
            setWide(wide);
        }
    
        public double getLength() {
            return length;
        }
    
        public void setLength(double length) {
            assert length > 0.0 : "您的输入有误,长方形的长不能小于0";
            this.length = length;
        }
    
        public double getWide() {
            return wide;
        }
    
        public void setWide(double wide) {
            assert wide > 0.0 : "您的输入有误,长方形的宽不能小于0";
            this.wide = wide;
        }
    
        public double area() {
            return this.length * this.wide;
    
        }
        public double circumference() {
            return 2 * (this.wide + this.length);
        }
    
        public boolean equals(Object obj) {
            if (this == obj) { //判断一下如果是同一个对象直接返回true,提高效率
                return true;
            }
            if (obj == null || obj.getClass() != this.getClass()) { //如果传进来的对象为null或者二者为不同类,直接返回false
                return false;
            }
            //也可以以下方法:
    //        if (obj == null || !(obj instanceof Rectangle)) { //如果传进来的对象为null或者二者为不同类,直接返回false
    //            return false;
    //        }
            Rectangle rectangle = (Rectangle) obj; //向下转型
            //比较长宽是否相等,注意:浮点数的比较不能简单地用==,会有精度的误差,用Math.abs或者Double.compare
            return Double.compare(rectangle.length, length) == 0 && Double.compare(rectangle.wide, wide) == 0;
        }
    
        public int hashCode() { //重写equals的同时也要重写hashCode,因为同一对象的hashCode永远相等
            return Objects.hash(length, wide); //调用Objects类,这是Object类的子类
        }
    
        public String toString() {
            return "Rectangle{" + "length=" + length + ", wide=" + wide + '}';
        }
    }
    
    public class TestDemo {
        public static void main(String[] args) {
    
            Rectangle rectangle1 = new Rectangle(3.0, 2.0);
            Rectangle rectangle2 = new Rectangle(3.0, 2.0);
            
            System.out.println(rectangle1.equals(rectangle2));
            System.out.println("rectangle1哈希码:" + rectangle1.hashCode() +
                    "\nrectangle2哈希码:" + rectangle2.hashCode());
            System.out.println("toString打印信息:" + rectangle1.toString());
        }
    }
    

    3、getClass和instanceof优缺点

    具体实现思路在代码中讲的很清楚了,我们这里重点分析一下getClass和instanceof两种实现方法的优缺点:
    在这里插入图片描述

    将代码逻辑简化一下:
    我们就重点看这段简单的代码

    //getClass()版本
    public class Student {
    	private String name;
    	
        public void setName(String name) {
            this.name = name;
        }
    	@Override
    	public boolean equals(Object object){
    		if (object == this)
    			return true;
    		// 使用getClass()判断对象是否属于该类
    		if (object == null || object.getClass() != getClass())
    			return false;
    		Student student = (Student)object;
    		return name != null && name.equals(student.name);
    }
    

    事实上两种方案都是有效的,区别就是getClass()限制了对象只能是同一个类,而instanceof却允许对象是同一个类或其子类,这样equals方法就变成了父类与子类也可进行equals操作了,这时候如果子类重定义了equals方法,那么就可能变成父类对象equlas子类对象为true,但是子类对象equlas父类对象就为false了,如下所示:

    class GoodStudent extends Student {
    
        @Override
        public boolean equals(Object object) {
            return false;
        }
    
        public static void main(String[] args) {
            GoodStudent son = new GoodStudent();
            Student father = new Student();
    
            son.setName("test");
            father.setName("test");
    
    		// 当使用instance of时
            System.out.println(son.equals(father)); // 这里为false
            System.out.println(father.equals(son)); // 这里为true
    
    		// 当使用getClass()时
            System.out.println(son.equals(father)); // 这里为false
            System.out.println(father.equals(son)); // 这里为false	
        }
    }
    

    注意看这里用的是getClass()
    在这里插入图片描述

    返回值两个都是false,符合我们的预期,(连类都不一样那肯定得为false啊)
    在这里插入图片描述

    而换成instanceof试试看咯:
    在这里插入图片描述

    运行结果:一个为true一个为false,很明显出现问题了。
    在这里插入图片描述

    这里的原因如下:
    instanceof的语法是这样的:
    当一个对象为一个类的实例时,结果才为true。但它还有一个特点就是,如果当这个对象是其子类的实例时,结果也会为true。这便导致了上述的bug。也就是说当比较的两个对象,他们的类是父子关系时,instanceof可能会出现问题。需要深究的小伙伴可以自己去了解一哈,所以在这里建议在实现重写equals方法时,尽量使用getClass来实现。
    在重写equals方法的同时需要重写hashCode方法,具体原因可能后续会讲到~~

    4、instanceof和getClass总结

    区别就是getClass()限制了对象只能是同一个类,而instanceof却允许对象是同一个类或其子类,

    5、instanceof实战

    public class GenericTest01 {
        public static void main(String[] args) {
            // 使用JDK5之后的泛型机制
            // 使用泛型List<Animal>之后,表示List集合中只允许存储Animal类型的数据。
            // 用泛型来指定集合中存储的数据类型。
            List<Animal> myList = new ArrayList<Animal>();
    
            // 指定List集合中只能存储Animal,那么存储String就编译报错了。
            // 这样用了泛型之后,集合中元素的数据类型更加统一了。
            //myList.add("abc");
    
            Cat c = new Cat();
            Bird b = new Bird();
    
            myList.add(c);
            myList.add(b);
    
            // 获取迭代器
            // 这个表示迭代器迭代的是Animal类型。
            Iterator<Animal> it = myList.iterator();
            while(it.hasNext()){
                // 使用泛型之后,每一次迭代返回的数据都是Animal类型。
                //Animal a = it.next();
                // 这里不需要进行强制类型转换了。直接调用。
                //a.move();
    
                // 调用子类型特有的方法还是需要向下转换的!
                Animal a = it.next();
                if(a instanceof Cat) {
                    Cat x = (Cat)a;
                    x.catchMouse();
                }
                if(a instanceof Bird) {
                    Bird y = (Bird)a;
                    y.fly();
                }
            }
        }
    }
    
    class Animal {
        // 父类自带方法
        public void move(){
            System.out.println("动物在移动!");
        }
    }
    
    class Cat extends Animal {
        // 特有方法
        public void catchMouse(){
            System.out.println("猫抓老鼠!");
        }
    }
    
    class Bird extends Animal {
        // 特有方法
        public void fly(){
            System.out.println("鸟儿在飞翔!");
        }
    }
    
    
    
    展开全文
  • 重写

    目录

    1、equals方法

    2、hashcode方法

    3、hash算法

    4、重写equals方法

    5、重写HashCode方法


    在每个类中,重写equals方法的时侯,一定要重写hashcode方法。

    Object类中的equals方法,底层是通过==来进行比较,所以比较的是对象的内存地址

    1、equals方法


    2、hashcode方法

     

    Java中的hashCode方法就是根据一定的规则与对象相关信息(例如对象的存储地址,对象的字段等)映射成一个数组,这个数值就被称为散列值 

    3、hash算法


    就是将hashcode的得到的随机数(散列值),映射成固定长度的值

    Java中规定:

    (1)如果两个对象通过equals方法比较是相等的,那么它们的hashCode方法结果值也是相等的。

    (2)如果两个对象通过equals方法比较是不相等的,那么它们的hashCode方法结果值不一定不相等。

    很多情况下,我们比较对象并不需要比较对象的地址,而是只要是同一个类的不同对象,成员属性值相同,我们就认为是同一个对象

     上图所示,没有重写equals方法的情况下,这里的比较返回的是false(因为比较的是堆中的内存地址)。

    4、重写equals方法

    但是两个对象是同一个类,而且成员变量的值都是相同,所以我们可以认为是同一个对象,为了达到这个效果,就必须重写equals方法,让他们比较的是类的类型和成员变量的值

    这里发现equals比较的是对象的成员变量的值了,并不是比较的内存地址,但是两个对象的hashcode还是不相同,这就会导致如下问题

     HashSet有一个特性就是不能允许相同的值的存在,我们car1和car2对于我们来说就是同一个对象(同类型,同值),那么为什么会存在这个问题呢?

    我们知道HashSet底层是通过HashMap来实现的,HashMap的key就是我们存入HashSet中的值,而value是一个固定值(并不需要去管),而HashMap的底层是通过数组+链表+红黑树(>=1.8),hashmap底层在计算数组下标位置就是使用的hashcode去实现的hash算法,所以如果hashcode的值不同,计算出来的数字下标位置就有可能不同,所以就将car1和car2放在了不同的数组的位置,所以并不会进行覆盖(正常情况下如果hashcode相同,得到相同的数组下标位置,还需要进行equals来比较是否是同一个元素),所以这就导致Hashset不能起到去重的作用

    所以这里也是我们需要重写HashCode方法的原因

    5、重写HashCode方法

     

     这里可以看到,重写HashCode方法之后,两个实例对象的hashcode的值也就是相同的,HashSet也就能起到了去重的效果

    所以Java中规定,一般重写equals方法就要重写HashCode方法,也是为了保证在不同场景下使用不会出错

    展开全文
  • 重写equals()3. hashCode与equals的区别和联系3.1 Hash3.2 HashCode 1. == 与 equals的区别 如果两个引用类型变量使用==运算符,那么比较的是地址,它们分别指向的是否是同一地址的对象,结果一定是false,因为两...
  • 【Java比较学习】重写equals方法的安全写法

    千次阅读 多人点赞 2021-10-05 15:49:11
    重写equals方法的正确打开方式 正文开始@Assassin 目录:重写equals方法的正确打开方式1. 什么是equals方法?1.1 equals方法:2. 为什么要重写equals方法?2.1 举个例子吧~3. 分析equals源码:4. 正确重写equals方法...
  • 文章目录1、hashCode与equals两者之间的关系2、== 和equals的区别`3、为什么要重写equals()方法?4、重写equals()方法5、为什么要重写hashCode()方法?6、什么时候需要重写hashCode()方法?7、重写hashCode()方法: ...
  • 文章目录前言示例代码结构情景演示情景一:不重写equals与hashCode普通情况下使用在哈希存储结构下使用情景二:仅重写equals普通情况下使用在哈希存储结构下使用情景三:仅重写hashCode普通情况下使用在哈希存储结构...
  • 测试方法
  • 重写equals方法时必须重写hashcode 有规范: 1,当obj1.equals(obj2) 为 true 时,obj1.hashCode() == obj2.hashCode() 2,当obj1.equals(obj2) 为 false 时,obj1.hashCode() != obj2.hashCode() 原因: 如果只重写...
  • Object类是所有类的基类,Object类中有equals方法和hashcode方法。在Object类中:equals方法是通过==进行比较的,比较的是引用指向的对象,如果对象相同,那么就认为两个相等。hashcode方法是获取对象的特征码值,...
  • 主要介绍了浅谈java 重写equals方法的种种“坑”,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • Object 类是所有类的父类,其 equals 方法比较的是两个对象的引用指向的地址,hashcode 是一个本地方法,返回的是对象地址值。他们都是通过比较地址来比较对象是否相等的
  • 我们都知道java中的List集合是有序的,因此是可以重复的,而set集合是无序的,因此是不能重复的,那么怎么能保证不能被放入重复的元素呢,但靠equals方法一样比较的话,如果原来集合中以后又10000个元素了,那么放入...
  • 基于以上的java对于Set或者Map的实现要求,所以建议所以需要重写equals方法的类都要同时重写hashcode方法。 二、疑问 这时就会有人问,我就不重写,能发生啥? 那我就来装个逼 下面是我个人理解 1、若是重写equals...
  • 如何重写equals方法

    千次阅读 2021-05-13 10:28:59
    重写equals方法 我们都知道,如果不对equals方法进行重写的话,那么它默认比较的就是两个对象的地址值是否是一样的。但是我们往往需要比较的是对象的内容是否是一样的,除了几个内置重写了equals方法的类型,我们写...
  • 我们先来看Object的equals方法,也就是我们不重写equals时用的方法 public boolean equals(Object obj) { return (this == obj); } see,就是个==连接的,如果不是基本数据类型就比对象地址值 所以我们如果想...
  • 如果只重写equals方法,而不重写hashcode的方法,会造成hashcode的值不同,而equals()方法判断出来的结果为true。 在Java中的一些容器中,不允许有两个完全相同的对象,插入的时候,如果判断相同则会进行覆盖。这...
  • 为什么重写equals时必须要重写hashCode方法 首先让我们看一下关于hashCode的规定: 对象相等,hashCode一定相等 对象不相等,hashCode可能相等 hashCode相等,对象不一定相等 hashCode不相等,对象一定不...
  • 为什么重写equals方法要重写HashCode方法 一、为什么重写equals方法要重写HashCode方法 在Object类中HashCode和equals是具有相同表现的 ① 如果两个对象equals为F,则表示两个对象的地址不同,则对应的HashCode不同...
  • 在我们平时编写Java代码时,重写equals方法时一定要重写hashCode方法,这是为什么呢? 在讨论这个问题前,我们先看下Object类中hashCode方法和equals方法。 hashCode方法: 翻译如下: equals方法: 翻译如下: ...
  • 其实每个类都有一个equals方法和hashcode方法。因为所有的类都继承自Object类。Object类中定义如下: equals中使用的双等于号进行比较,所以进行比较的是对象的引用。并且这两个方法都未被final修饰,所以都...
  • 重写java object类的equals方法 覆盖equals方法请遵守约定 什么情况下要覆盖equals方法 容易违反的对称性 不易察觉的传递性 覆盖equals请遵守通用约定 似乎覆盖equals方法看起来似乎是一件平常甚至极其简单的事情...
  • 在每个类中,在重写 equals 方法的时侯,一定要重写 hashcode 方法。如果不这样做,你的类违反了 hashCode的通用约定, 这会阻止它在 HashMap 和 HashSet 这样的集合中正常工作。 根据 Object 规范,以下时具体约定...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 217,910
精华内容 87,164
关键字:

重写equals方法

友情链接: C - Elements of Style.zip