V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lmybill
V2EX  ›  Java

Java 里的 equals 方法

  •  
  •   lmybill · 2023-06-08 13:57:14 +08:00 · 2549 次点击
    这是一个创建于 569 天前的主题,其中的信息可能已经有所发展或是发生改变。

    equals 本来比较的是两个对象是否是同一个对象,到 String 等类里却重写为比较值是否相等,这是不是改变了这个方法的原来意思,给人造成很大困扰

    29 条回复    2023-06-09 10:30:33 +08:00
    lalawu
        1
    lalawu  
       2023-06-08 13:58:27 +08:00
    要判断是否同一个对象直接用等号
    msg7086
        2
    msg7086  
       2023-06-08 13:59:46 +08:00
    equals 就是含义比较啊。

    equals
    public boolean equals(Object obj)
    Indicates whether some other object is "equal to" this one.
    Nooooobycat
        3
    Nooooobycat  
       2023-06-08 13:59:51 +08:00
    ????

    判断是否同一个对象,是用 == 呀(地址相同则是同一个对象)

    .equal 就是判断两个对象的逻辑值是否相同的
    totoro52
        4
    totoro52  
       2023-06-08 13:59:55 +08:00
    都叫方法了,那具体实现不就看个人了
    twofox
        5
    twofox  
       2023-06-08 14:00:01 +08:00
    因为字符串会放进常量池,是会复用的,没有影响
    sentinelK
        6
    sentinelK  
       2023-06-08 14:00:20 +08:00
    “equals 本来比较的是两个对象是否是同一个对象”
    恰恰相反,对比两个变量是否引用一个对象用 ==

    equals 是一个可重写的方法,你愿意比较什么,就是什么。同理,toString()一样。
    wolfie
        7
    wolfie  
       2023-06-08 14:00:21 +08:00
    Override 是非常基础的概念,自己翻翻书吧。
    TWorldIsNButThis
        8
    TWorldIsNButThis  
       2023-06-08 14:03:03 +08:00 via iPhone
    是否同一个,那是比较 identity
    对于数据库 entity 来说通常就是 id 字段
    laoyur
        9
    laoyur  
       2023-06-08 14:09:55 +08:00
    正文第一句话就错了
    ruanimal
        10
    ruanimal  
       2023-06-08 14:10:33 +08:00
    这个问题和 java 反对运算符重载是一个意思
    gaifanking
        11
    gaifanking  
       2023-06-08 14:12:38 +08:00
    我理解楼主的意思是 String 类的 equals 方法破坏了 Object 类的 equals 定义
    但是我们看 Object 对 equals 返回的定义:
    Returns: true if this object is the same as the obj argument; false otherwise.

    这里面的 same ,在英语里即可以表示同一个,也可以表示一模一样(指两个)
    再看 equal 的英文含义,即可以表示相同,也可以表示相等

    所以并没有什么错误,有几楼没理解吧 扯了一堆没用的。
    lmybill
        12
    lmybill  
    OP
       2023-06-08 14:14:08 +08:00
    override 可以修改具体实现,但是不能修改方法的含义。对象的相等和对象里属性的值相等不应该是同一个意思。或者说 equals 这个方法本身定义就有点问题,模糊不清
    JasonLaw
        13
    JasonLaw  
       2023-06-08 14:23:00 +08:00
    我不明白你是怎么得出“equals 本来比较的是两个对象是否是同一个对象”这个结论的,可以给一下你的论证吗?

    https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Object.html#equals(java.lang.Object)

    文档上是这么说的。

    The equals method implements an equivalence relation on non-null object references:

    * It is reflexive: for any non-null reference value x, x.equals(x) should return true.
    * It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
    * It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
    * It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
    * For any non-null reference value x, x.equals(null) should return false.
    LeegoYih
        14
    LeegoYih  
       2023-06-08 14:23:26 +08:00
    #12
    按你这么说还要 equals 干嘛?这 API 删了,都用==不就完了?
    没重写当然是对比地址,重写了就按重写了的逻辑达成共识,对比值用 equals ,对比对象用==
    JasonLaw
        15
    JasonLaw  
       2023-06-08 14:24:29 +08:00
    @JasonLaw 它后面也说了

    The equals method for class Object implements **the most discriminating possible** equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true). In other words, under the reference equality equivalence relation, each equivalence class only has a single element.
    28Sv0ngQfIE7Yloe
        16
    28Sv0ngQfIE7Yloe  
       2023-06-08 14:29:45 +08:00
    🤣 就是大家对 equal 的诉求不一样,所以才给你重写的机会呀
    nothingistrue
        17
    nothingistrue  
       2023-06-08 15:00:39 +08:00
    java.lang.Objects#equals Javadoc 的标题是:「 Indicates whether some other object is "equal to" this one.」 楼主脑回路不正常,理解成了「 Indicates whether some other object and this one is "the same one".」 然后接下来后面的人也照着这个思路去解释了。这真应了那句话:不要和白痴争辩,因为他会把你的智商拉到和他同一水平,然后用丰富的经验打败你。
    x77
        18
    x77  
       2023-06-08 15:04:22 +08:00
    坏消息是别的语言也这么定义:equals 用来判断对象的内容是否相同,== 用来判断是否同一个对象。
    好消息是多数语言的 String 都提供 Compare 方法。
    NeroKamin
        19
    NeroKamin  
       2023-06-08 15:31:21 +08:00
    麻烦问问题之前先看看文档好吗,谁说 equals 是用来比较两个对象是否是同一个对象的,你说的那个是==
    m2276699
        20
    m2276699  
       2023-06-08 15:47:47 +08:00
    @nothingistrue 哥们,何必要攻击别人
    lyusantu
        21
    lyusantu  
       2023-06-08 16:01:10 +08:00
    写注释的人都没你们想得多
    Koril
        22
    Koril  
       2023-06-08 16:12:38 +08:00
    “equals 本来比较的是两个对象是否是同一个对象”——这句话是不是存在问题?用 == 判断是不是一个对象,而覆写 equals 的情况,是类具有自己特有的“逻辑相等”的概念,和对象等同的概念不一样,一般发生在“值类”中,我没理解错的话,String 也是值类的一种。
    RoccoShi
        23
    RoccoShi  
       2023-06-08 20:33:20 +08:00
    "先问是不是,再问为什么"
    siweipancc
        24
    siweipancc  
       2023-06-08 23:05:22 +08:00 via iPhone
    你对语言的定义理解有偏差,看看别语言也是同样的逻辑的,你就说不出话了
    tairan2006
        25
    tairan2006  
       2023-06-09 09:05:19 +08:00
    第一句就错了啊… == 才是用来判断同一个对象的。

    至于别的语言,能重载操作符的肯定能实现任意语义;有指针的语言可以直接比较指针;各有各的思路吧。
    gaifanking
        26
    gaifanking  
       2023-06-09 09:55:45 +08:00
    @nothingistrue 人家说 Object ,你自作主张加个复数变成 Objects 干啥?
    仔细看 Object 的 equals 定义 Returns 部分:
    true if this object "is the same" as the obj argument; false otherwise.
    gaifanking
        27
    gaifanking  
       2023-06-09 10:03:23 +08:00
    @tairan2006 @Koril @LeegoYih @Nooooobycat
    楼主是从面向对象的设计角度提问的,跟==没有一毛钱关系
    OO 原则里有一条叫里氏替换,子类覆盖父类方法时,可以修改算法规则,但不能改变父类原意。

    楼主的疑问我在前面已经回答了:
    same ,在英语里即可以表示同一个,也可以表示一模一样(指两个)
    equal , 在英文里即可以表示相同,也可以表示相等

    还不清楚自己查词典吧
    @lmybill
    nothingistrue
        28
    nothingistrue  
       2023-06-09 10:30:19 +08:00   ❤️ 1
    放上 Object.equals 方法的 javadoc 的,8 英文原版、8 中文机器翻译、上古 1.6 官方中文版本,免得白痴再通过以偏概全、扣字眼来拉低水平。

    另提示:Object 作为最高基类,具备模板的作用,但它既不是接口,也不是虚拟类; Object 的方法都是实际方法,不是接口方法,也不是虚拟类,在阅读这类方法的 Javacod 时,需要区分好哪些是说自己的,哪些是说给子类的。




    __JDK 8 英文原版__
    Indicates whether some other object is "equal to" this one.

    The equals method implements an equivalence relation on non-null object references:

    It is reflexive: for any non-null reference value x, x.equals(x) should return true.
    It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
    It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
    It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
    For any non-null reference value x, x.equals(null) should return false.

    The equals method for class Object implements the most discriminating possible equivalence relation on objects; that is, for any non-null reference values x and y, this method returns true if and only if x and y refer to the same object (x == y has the value true).

    Note that it is generally necessary to override the hashCode method whenever this method is overridden, so as to maintain the general contract for the hashCode method, which states that equal objects must have equal hash codes.

    Parameters:
    obj - the reference object with which to compare.
    Returns:
    true if this object is the same as the obj argument; false otherwise.
    See Also:
    hashCode(), HashMap

    __JDK 8 机翻__
    指示某个其他对象是否“等于”这个对象。

    equals 方法在非空对象引用上实现等价关系:

    它是自反的:对于任何非空引用值 x ,x.equals(x) 应该返回 true 。
    它是对称的:对于任何非空引用值 x 和 y ,当且仅当 y.equals(x) 返回真时,x.equals(y) 应该返回真。
    它是传递性的:对于任何非空引用值 x 、y 和 z ,如果 x.equals(y) 返回 true 并且 y.equals(z) 返回 true ,则 x.equals(z) 应该返回 true 。
    它是一致的:对于任何非空引用值 x 和 y ,多次调用 x.equals(y) 始终返回 true 或始终返回 false ,前提是在对象的 equals 比较中使用的信息没有被修改。
    对于任何非空引用值 x ,x.equals(null) 应该返回 false 。

    类 Object 的 equals 方法在对象上实现了最具鉴别力的可能等价关系; 也就是说,对于任何非空引用值 x 和 y ,当且仅当 x 和 y 引用同一对象( x == y 的值为 true )时,此方法才返回 true 。

    请注意,通常需要在重写此方法时重写 hashCode 方法,以维护 hashCode 方法的一般契约,该契约规定相等的对象必须具有相等的哈希码。

    参数:
    obj - 要与之比较的引用对象。
    返回:
    如果此对象与 obj 参数相同,则为真;否则为真。 否则为假。
    也可以看看:
    hashCode(), HashMap
    nothingistrue
        29
    nothingistrue  
       2023-06-09 10:30:33 +08:00
    __JDK 1.6 SUN 认证的志愿者翻译__

    指示其他某个对象是否与此对象“相等”。

    equals 方法在非空对象引用上实现相等关系:

    自反性:对于任何非空引用值 x ,x.equals(x) 都应返回 true 。
    对称性:对于任何非空引用值 x 和 y ,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true 。
    传递性:对于任何非空引用值 x 、y 和 z ,如果 x.equals(y) 返回 true ,并且 y.equals(z) 返回 true ,那么 x.equals(z) 应返回 true 。
    一致性:对于任何非空引用值 x 和 y ,多次调用 x.equals(y) 始终返回 true 或始终返回 false ,前提是对象上 equals 比较中所用的信息没有被修改。
    对于任何非空引用值 x ,x.equals(null) 都应返回 false 。

    Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 y ,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true ( x == y 具有值 true )。

    注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。

    参数:
    obj - 要与之比较的引用对象。
    返回:
    如果此对象与 obj 参数相同,则返回 true ;否则返回 false 。
    另请参见:
    hashCode(), Hashtable
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2840 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 14:06 · PVG 22:06 · LAX 06:06 · JFK 09:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.