字符串类中的Object的equals方法和自定义类中的Object的equal方法之间有什么区别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字符串类中的Object的equals方法和自定义类中的Object的equal方法之间有什么区别相关的知识,希望对你有一定的参考价值。

我无法理解String类中equals方法的行为(区分),然后在自定义类中手动覆盖equals方法。

根据java,如果我们希望两个对象相等,那么我们应该重写equals方法以检查它们之间的相等性。因此,我制作了一个Dog类并在该类中重写equals方法。为了进一步检查对象之间的相等性,我使用了Set类型集合,因为它不允许重复。但是我很困惑看到输出。这是我的代码:

import java.util.*;

class Dog
    int type;

    public int getType() 
        return type;
    
    public void setType(int type) 
        this.type = type;
    

    public boolean equals(Object o)
    if((o instanceof Dog) && ((Dog)o).getType()==this.getType())
        return true;
    
    else
        return false;
    


public class CheckEquality 
    public static void main(String[] args) 
        Dog d1=new Dog();
        Dog d2=new Dog();

        d1.setType(12);
        d2.setType(12);
        Set set=new HashSet();
        if(set.add(d1))
            System.out.println("d1 added");
        
        if(set.add(d2))
            System.out.println("d2 added");
        

        String s1=new String("ad");
        String s2=new String("ad");
        //String s1="ad";
        //String s2="ad";
        Set set2=new HashSet();
        if(set2.add(s1))
            System.out.println("s1 added");
        
        if(set2.add(s2))
            System.out.println("s2 added");
        

    

输出:

d1 added
d2 added
s1 added

我期望的是:

d1 added
s1 added

谁能告诉我为什么得到d2 addedd语句,当可以看到具有相同type的对象已经被添加到Set时。

相反,String不允许语句s2 added。为什么会这样呢?任何人都可以消除我的疑虑。

答案

您缺少hashCode方法。

[此哈希值在存储或处理 实例–这些值旨在均匀分布以进行变化 输入以便在聚类中使用。此属性对 哈希表和其他存储的数据结构的性能 组中的对象(“存储桶”)基于其计算的哈希值

您可以使用Objects类生成哈希码。

public class Dog 
    @Override
    public int hashCode() 
        return Objects.hash(type);
    

另一答案

因为还必须覆盖hashCode。检查Object#equals的合同:

[注意,通常必须重写hashCode方法,以保持hashCode方法的常规约定,该约定规定相等的对象必须具有相等的哈希码。

将此添加到您的Object#equals类:

Dog

这只是一个基本示例。如果public class Dog @Override public int hashCode() return this.type; type字段会更好。从final

[只要在Java应用程序执行期间在同一对象上多次调用它,则Object#hashCode方法必须一致地返回相同整数,前提是未修改该对象的相等比较中使用的信息。从一个应用程序的执行到同一应用程序的另一执行,此整数不必保持一致。

另一答案

Object#hashCode实现hashCode期望通过使用Set查找值。您的对象没有提供良好的hashCode,而是使用了HashSet中的版本。当实现等于时,通常还应该始终实现hashCode。这只是一个最佳实践

在Java 8中,您可以使用以下代码来提供良好而有效的哈希值:

Object

如果使用正确,hashCode将按预期工作。对于简单的Objects.hash(value1, value2, value3); 类,可以返回HashSet,但对于包含更多属性的更复杂的对象,建议使用Dog或类似属性。

另一答案

如果不重写哈希码方法,则在将对象存储在哈希集中时会出现冲突问题。哈希集在内部使用哈希表来键和值对。

因为您必须重写哈希码,以便哈希集找到相同的哈希码,然后它将在内部调用equals方法。

type

以上是关于字符串类中的Object的equals方法和自定义类中的Object的equal方法之间有什么区别的主要内容,如果未能解决你的问题,请参考以下文章

重写Object类中的equals方法

Object类中的toString(),equals(), hashCode()方法之间的关系

== 与 equals()方法的区别

重写java类的equals()和hashCode方法

Java基础-equals方法

equals