ArrayList的contains()方法如何评估对象?

Man*_*tis 292 java evaluation arraylist object

假设我创建了一个对象并将其添加到我的对象中ArrayList.如果我然后使用完全相同的构造函数输入创建另一个对象,那么该contains()方法是否会将两个对象评估为相同?假设构造函数对输入没有做任何有趣的事情,并且存储在两个对象中的变量是相同的.

ArrayList<Thing> basket = new ArrayList<Thing>();  
Thing thing = new Thing(100);  
basket.add(thing);  
Thing another = new Thing(100);  
basket.contains(another); // true or false?
Run Code Online (Sandbox Code Playgroud)
class Thing {  
    public int value;  

    public Thing (int x) {
        value = x;
    }

    equals (Thing x) {
        if (x.value == value) return true;
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是class应该如何实现contains()回归true

Bin*_*erd 328

ArrayList implements列表接口.

如果你看一下Javadoc文档Listcontains方法,你会看到它使用的equals()方法来评估,如果两个对象是相同的.

  • 如果您计划覆盖equals(),请确保您也覆盖hashcode()方法.如果您不习惯,使用集合时可能无法正常工作? (61认同)
  • 这是一个正确的答案,但请注意,您需要更改equals方法以接受`Object`而不是`Thing`.如果不这样做,则不会使用equals方法.:) (33认同)
  • Collections以一种优化的方式完成任务,这意味着contains()首先检查两个对象的hashCode,然后才调用equals()。如果`hashCode`是不同的(Thing的两个不同实例总是如此),则不会调用`equals()`方法。根据经验,当覆盖`equals()`时,也不要忘记覆盖`hashCode()`。 (3认同)

Chr*_*CVB 52

我认为正确的实施应该是

public class Thing
{
    public int value;  

    public Thing (int x)
    {
        this.value = x;
    }

    @Override
    public boolean equals(Object object)
    {
        boolean sameSame = false;

        if (object != null && object instanceof Thing)
        {
            sameSame = this.value == ((Thing) object).value;
        }

        return sameSame;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • `hashcode`方法的实现在哪里? (11认同)
  • 是的,你是对的@Alex!随意添加;) (10认同)
  • `object!= null`条件是不必要的,因为`object instanceof Thing`也检查对象是否也为空. (3认同)

Bhu*_*ale 15

ArrayList使用在类(您的案例Thing类)中实现的equals方法来进行equals比较.


ale*_*loh 12

通常,您也应该在hashCode()每次覆盖时覆盖equals(),即使只是为了提升性能.HashCode()在进行比较时,决定对象被分类到哪个"桶",因此任何两个equal()评估为true的对象都应返回相同的值hashCode value().我不记得它的默认行为hashCode()(如果它返回0,那么你的代码应该工作但是很慢,但是如果它返回地址那么你的代码就会失败).当我的代码失败时,我确实记得很多次,因为我忘了覆盖hashCode()了.:)


Yis*_*hai 7

它在对象上使用equals方法.因此,除非Thing覆盖equals并使用存储在对象中的变量进行比较,否则它将不会在contains()方法上返回true .


小智 6

class Thing {  
    public int value;  

    public Thing (int x) {
        value = x;
    }

    equals (Thing x) {
        if (x.value == value) return true;
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

你必须写:

class Thing {  
    public int value;  

    public Thing (int x) {
        value = x;
    }

    public boolean equals (Object o) {
    Thing x = (Thing) o;
        if (x.value == value) return true;
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在它有效;)

  • 你不应该做事情x =(事情)o; 没有先检查另一个对象是否为空 (6认同)

Can*_*ner 5

只是想要注意,当value不是基本类型时,以下实现是错误的:

public class Thing
{
    public Object value;  

    public Thing (Object x)
    {
        this.value = x;
    }

    @Override
    public boolean equals(Object object)
    {
        boolean sameSame = false;

        if (object != null && object instanceof Thing)
        {
            sameSame = this.value == ((Thing) object).value;
        }

        return sameSame;
    }
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我提出以下建议:

public class Thing {
    public Object value;  

    public Thing (Object x) {
        value = x;
    }

    @Override
    public boolean equals(Object object) {

        if (object != null && object instanceof Thing) {
            Thing thing = (Thing) object;
            if (value == null) {
                return (thing.value == null);
            }
            else {
                return value.equals(thing.value);
            }
        }

        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)