equals和==的区别是啥?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了equals和==的区别是啥?相关的知识,希望对你有一定的参考价值。

解释一下==号,他比较的是一个对象在内存中的地址值,
比如2个字符串对象
String s1 = new String("str");
String s2 = new String("str");
如果用==号比较,会返回false,因为创建了两个对象,他们在内存中地址的位置是不一样的。

equals的情况比较复杂,它是java.lang.Object类中的一个方法。因为java中所有的类都默认继承于Object,所以所有的类都有这个方法。

在Object类源码中是这样写的。
public boolean equals(Object obj)
return (this == obj);

他同样使用==号进行内存地址的比较。但是许多java类中都重写了这个方法,比如String。
public boolean equals(Object anObject)
if (this == anObject)
return true;

if (anObject instanceof String)
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count)
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0)
if (v1[i++] != v2[j++])
return false;

return true;


return false;


String里的方法,如果==号比较不相等,还会进行一下值的比较。
所以equals方法具体的作用要看当前的那个类是如何实现重写父类中该方法的。如果没有重写该方法,那么他和==号等价。
参考技术A “==”是关系运算符,equals()是方法,同时他们的结果都返回布尔值;
“==”使用情况如下:
1) 基本类型,比较的是值
2) 引用类型,比较的是地址
3) 不能比较没有父子关系的两个对象
equals()方法使用如下:
1) 系统类一般已经覆盖了equals(),比较的是内容。
2) 用户自定义类如果没有覆盖equals(),将调用父类的equals (比如是Object),而Object的equals的比较是地址(return (this == obj);)
3) 用户自定义类需要覆盖父类的equals()
注意:Object的==和equals比较的都是地址,作用相同

IEqualityComparer 实现中 GetHashCode 和 Equals 之间的关系是啥? [复制]

【中文标题】IEqualityComparer 实现中 GetHashCode 和 Equals 之间的关系是啥? [复制]【英文标题】:What's the relation between GetHashCode and Equals in a IEqualityComparer implementation? [duplicate]IEqualityComparer 实现中 GetHashCode 和 Equals 之间的关系是什么? [复制] 【发布时间】:2014-04-08 07:48:14 【问题描述】:

我有一个继承自 B 类并实现 IEqualityComparer<A> 的类 A。 这意味着 A 类提供了自己的 Equals 和 GetHashCode 方法的实现。到目前为止,一切都很好。 问题是我不明白为什么代码的行为方式如下:

只有当 A 的 GetHashCode 实现返回时,调试器才会到达 A 的 Equals 实现断点 this.GetHashCode() 而不是 obj.GetHashCode(),其中“obj”是 GetHashCode 的签名定义的参数(在我的例子中是 A 类型的变量)。

直觉上,我认为我应该返回收到的对象的哈希码,但这样做会使编译器忽略实例的 Equals 实现。

为什么会这样?

代码演示:

public class A : B, IEqualityComparer<A>

    public bool Equals(A x, A y)
    
        //my implementation...
    

    public int GetHashCode(A obj)
    
        //return obj.GetHashCode(); -> this makes my Equals implementation above be ignored! Why?
        return this.GetHashCode(); -> my Equals implementation is used
    

【问题讨论】:

你能贴一些代码来解释这个问题吗,很难猜对 【参考方案1】:

听起来您使用了错误的界面。 IEqualityComparer&lt;&gt; 通常用于比较其他类型实例的类。

你的类型应该简单地实现IEquatable&lt;A&gt; 覆盖Equals(object)GetHashCode()。注意签名。

像这样:

public class A : B, IEquatable<A>

    public bool Equals(A other)
    
       if (other == null || GetType() != other.GetType())
           return false;

       //your implementation
    

    public override bool Equals(object obj)
    
        return Equals(obj as A);
    

    public override int GetHashCode()
    
        //your implementation
    

然后您可以执行someEnumerableOfA.Distinct() 之类的操作,Linq 方法将使用您的实现。

另一种选择是:

public class A : B // no interfaces



public class AEqualComparer : IEqualityComparer<A>

    public bool Equals(A x, A y)
    
       //your implementation
    

    public int GetHashCode(A x)
    
        //your implementation
    

使用此其他选项,您需要someEnumerableOfA.Distinct(new AEqualComparer ())

【讨论】:

我选择 IEqualityComparer 的原因是因为我的解决方案依赖于调用 IEnumerable.Distinct(IEqualityComparer)。换句话说,如果我想返回我的集合的不同元素,为什么我不能在这里使用 Distinct 并因此需要提供 IEqualityComparer 实现? OP 实现了正确的接口,但方式错误。有关更多信息,请参阅链接的重复线程。 @Veverke,如果您覆盖 EqualsGetHashCode,则无需实现或提供 IEqualityComparer&lt;T&gt; @SriramSakthivel 不同意。你不应该有一个类A 实现IEqualityComparer&lt;A&gt;。那是滥用。看看String 类。它实现了IEquatable&lt;String&gt;。但是,还有其他类,例如实现 IEqualityComparer&lt;String&gt;StringComparer(但 IEqualityComparer&lt;StringComparer&gt;)。 @Jodrell:我对 Distinct 的 IEnumerable 调用将如何? variable.Distinct(this) - 当前类在哪里覆盖 Equals 和 GetHashCode?​​span> 【参考方案2】:

实现IEqualityComparer&lt;T&gt; 不是override 的基本实现GetHashCodeEquals

实现IEqualityComparer&lt;T&gt; 允许您提供实现者的实例作为T 的相等比较器。这是几个 linq 扩展和通用集合构造函数的通用参数。

覆盖EqualsGetHashCode 会影响对类实例进行相等性测试的方式。利用调用 EqualsGetHashCode 的其他实现,例如基本 =!= 运算符和 linq 扩展和通用集合构造函数,您不提供替代 IEqualityComparer&lt;T&gt;

这些概念相似,但用途不同,不能部分互换


让我用一个例子来扩展,

public class A

    public string Value1  get; set; 
    public int Value2  get; set; 

    public override int GetHashCode()
    
        unchecked
        
            int hash = 17;
            hash = (hash * 23) + 
                StringComparer.Ordinal.GetHashCode(this.Value1);
            hash = (hash * 23) + this.Value2;
            return hash;
        
    

    public override bool Equals(object obj)
    
        var a = obj as A;
        if (a == null)
        
            return false;
        

        if (a.Value2 != this.Value2)
        
            return false;
        

        return StringComparer.Ordinal.Equals(
            a.Value1,
            this.Value1);
    

A的这个实现正确地覆盖了EqualsGetHashCode,这个改变足以保证在调用linq扩展之后

var distinct = aSequneceOfA.Distinct();

distinct 不会包含具有相同Value2 和通常可比较Value1 的任何实例。无需其他接口实现即可实现此目的。


现在,假设在某些情况下我对Value1 的这个序数比较不满意,也许我需要不区分大小写。我可能会实现一个新的相等比较器。

public class AComparerInsensitive : IEqualityComparer<A>

    public bool Equals(A x, A y)
    
        if (x == null)
        
            return y == null;
        

        if (y == null)
        
            return false;
        

        if (x.Value2 != y.Value2)
        
            return false;
        

        return StringComparer.CurrentCultureIgnoreCase.Equals(
            x.Value1,
            y.Value1)
    

    public int GetHashCode(A a)
    
        if (a == null)
        
            return 0;
        

        unchecked
        
            int hash = 17;
            hash = (hash * 23) + 
                StringComparer.CurrentCultureIgnoreCase.GetHashCode(
                    a.Value1);
            hash = (hash * 23) + a.Value2;
            return hash;
        
    

这将允许我调用 Distinct 的替代重载,

var insensitivelyDistinct = aSequneceOfA.Distinct(
    new AComparerInsensitive());

这种重载的不同忽略 As 被覆盖 EqualsGetHashCode 并使用 AComparerInsensitive 执行比较。

【讨论】:

@Veverke 我希望我的扩展答案能让事情更清楚。

以上是关于equals和==的区别是啥?的主要内容,如果未能解决你的问题,请参考以下文章

请问各位大佬这道java的重写equals和重写hashcode方法内部是啥意思呀?

"".equals--双引号的equals是啥意思?跪求解释

Java里的equals和==的区别是否equals是比较内容,==是比较地址的?

IEqualityComparer 实现中 GetHashCode 和 Equals 之间的关系是啥? [复制]

.equals()到底是啥意思?

equals和==区别 ,equals和hashcode区别