当我们有 == 运算符时,为什么要使用 equals() 方法? [重复]

问题描述 投票:0回答:8

当我看到

equals()
方法的实现时,它什么也没做,但与
==
所做的相同。所以我的问题是,当我们有
==
运算符执行相同的工作时,需要将其作为单独的方法吗?

java equals referenceequals
8个回答
44
投票

您不能重载

==
运算符,但如果您希望它的行为与
equals(Object)
运算符不同,您可以覆盖
==
,即不比较引用,而是实际比较对象(例如,使用它们的全部或部分字段) ).

此外,如果您确实覆盖了

equals(Object)
,也请查看
hashCode()
。这两种方法需要兼容(即根据
equals(Object)
相等的两个对象需要具有相同的
hashCode()
),否则会出现各种奇怪的错误(例如将对象添加到集合或地图时)。


35
投票

==
比较对象references,询问两个引用是否相同。

equals()
比较对象内容,并询问对象是否代表相同的概念。


19
投票

对于原语

==
运算符检查两个是否相同。
如果它不是基元,它会检查它是否是两个指针(或引用指向对象的同一个实例。

equals()
方法执行自定义检查,即在
Object
中使用
==
检查引用。但在其他课程中,有时
equals()
会被覆盖(我不知道这是否是正确的过去分词)
equals()
必须检查内容

所以,例如:

int i0 = 34;
int i1 = 34;
int i2 = 35;
// results
i0 == i1: true
i1 == i0: true
i2 == i0: false

但是如果我们有非原语

String str0 = new String("Hello man!");
String str1 = new String("Hello man!");
String str2 = new String("!nam olleH");
String str2copy = str2;
// Results
str0 == str1: false // Pointer to two different object, so == will give false
str1 == str2: false // Idem
str2 == str2copy: true // So this are two pointers to the same object
str0.equals(str1): true // This are not the same objects, but they are equal
str1 == str1: true // Again: two times a pointer to the same  object

那么,为什么

str0.equals(str1)
返回
true
?因为 String 类重写了
equals()
。在该方法中,它不会通过执行
return this == obj;
检查它们是否相等,但在该方法中,有一个完整的检查。我不知道他们使用哪种方法来比较两个字符串,但这里有两种可能的方法:

  • 从两个字符串生成哈希码并检查它们是否相等 (
    int == int
    )
  • 逐个字符检查是否相同。

所以我希望现在一切都清楚了。


2
投票

两者之间有一个非常重要的区别。

“==”比较对象实例。默认的 equals() 实现也执行此操作。请运行并分析以下代码示例:

public class Person{
   String name;

   public Person(String name){
       this.name = name;
   }

//overriding equals
public boolean equals( Object obj ) {
    if( this == obj )
        return true;
    if( obj == null )
        return false;
    if( getClass() != obj.getClass() )
        return false;
    Person other = (Person) obj;
    if( name == null ) {
            if( other.name != null )
            return false;
    } else if( !name.equals( other.name ) )
        return false;
    return true;
    }
     }

    ...
    ...
    Person john1 = new Person("John");
    Person john2 = new Person("John");
    System.out.println("john1 == john2:" + (john1 == john2));
    System.out.println("john1.equals(john2):" + john1.equals(john2));

如您所见,“==”将返回 false(对象是 Person 的两个不同实例),而 equals 将返回 true(因为我们定义了两个具有相同名称的 Person 是相等的)


2
投票

== 运算符用于比较引用。
equals() 方法是在对象定义上定义的。

Dog d =new Dog();
Collar c =new Collar("Red");
 d.setCollar(c);
Dog d2=new Dog();
 Collar c2=new Collar("Red");
d2.setCollar(c2);

 d2.getCollar() ==d.getCollar()

将返回 false 表明 两只狗有两个不同的项圈对象(项目)。它们不共享相同的项圈

d2.getCollar().equals(d.getCollar())

如果项圈定义为[如果项圈颜色相同,则项圈相同],则返回 true 两只狗有相同颜色的项圈。

   class Collar{
    String color="";
    public Collar(String p0){
    this.color=p0;
    }
    boolean equals(Object c){
      Collar other=(Collar)c;
      return  this.color.equals(other.getColor());
    }

    public String getColor(){
      return this.color;
    }
    }

1
投票

这样做是为了使这成为可能:

String s1 = new String("foo");
String s2 = new String("foo");

System.out.println(s1 == s2); // false?! Different references!
System.out.println(s1.equals(s2)); // true

如果您检查

String#equals()
的来源,您会发现它已适当地覆盖
Object#equals()
以比较彼此的内部字符数组(实际 值)。许多其他类也重写了此方法。


0
投票

在java中,如果操作数是原始数据类型,则等于运算符(==)对两个变量的数据进行操作。但是如果操作数是对象,java 会使用引用来比较它们,因为它无法确定比较对象的哪个或哪些字段。

因此,只有一种基于用户定义字段进行比较的方法,即通过重写 equals() 方法在对象中定义,因为 java 中不能重写 equals 运算符(==),因为 java 不支持运算符重写。

举个例子,如果你想根据名称比较 Employee,你需要通过重写 Employee 类中的 equals 方法来定义它的逻辑,如下所示:

public class Employee {
    private Integer id;
    private String name;

    @Override
    public boolean equals(Object obj) {
        Employee other = (Employee) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }


}

-1
投票

“string”==“string”将返回 false "string".equals("string") 将返回 true

当 o1 == o2 时,您可以比较对象 1 与 o2 是同一个对象(通过引用)

使用 o1.equals(o2),根据对象的不同,equals 方法会被重写,而不是用“return o1 == o2”之类的方法实现

例如您创建 2 个 Set 实例 这 2 个集合对象是 2 个不同的对象,您可以在其中任何一个中添加不同的元素。 set1 == set2 总是返回 false 但如果 set2 包含与 set1 完全相同的元素,set1.equals(set2) 最终将返回 true...并且因为 equals 方法在 Set 类中被重写...

Set 的 Equals 实现是:

      public boolean equals(Object o) {
        if (o == this)
           return true;

        if (!(o instanceof Set))
             return false;
        Set s = (Set) o;
        if (s.size() != c.size())
             return false;
        return containsAll(s); // Invokes safe containsAll() above
    }
© www.soinside.com 2019 - 2024. All rights reserved.