Java ArrayList 的 contains() 方法如何评估对象?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2642589/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does a ArrayList's contains() method evaluate objects?
提问by Mantas Vidutis
Say I create one object and add it to my ArrayList
. If I then create another object with exactly the same constructor input, will the contains()
method evaluate the two objects to be the same? Assume the constructor doesn't do anything funny with the input, and the variables stored in both objects are identical.
假设我创建了一个对象并将其添加到我的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?
class Thing {
public int value;
public Thing (int x) {
value = x;
}
equals (Thing x) {
if (x.value == value) return true;
return false;
}
}
Is this how the class
should be implemented to have contains()
return true
?
这是class
应该如何实施才能获得contains()
回报true
?
采纳答案by Binary Nerd
ArrayList implements
the List Interface.
ArrayList implements
List 接口。
If you look at the Javadoc for List
at the contains
method you will see that it uses the equals()
method to evaluate if two objects are the same.
如果您查看该方法的Javadoc,List
contains
您将看到它使用该equals()
方法来评估两个对象是否相同。
回答by Bhushan Bhangale
The ArrayList uses the equals method implemented in the class (your case Thing class) to do the equals comparison.
ArrayList 使用在类(您的案例 Thing 类)中实现的 equals 方法进行 equals 比较。
回答by Yishai
It uses the equals method on the objects. So unless Thing overrides equals and uses the variables stored in the objects for comparison, it will not return true on the contains()
method.
它在对象上使用 equals 方法。因此,除非 Thing 覆盖 equals 并使用存储在对象中的变量进行比较,否则它不会在contains()
方法上返回 true 。
回答by Kevin Day
Other posters have addressed the question about how contains() works.
其他海报已经解决了关于 contains() 如何工作的问题。
An equally important aspect of your question is how to properly implement equals(). And the answer to this is really dependent on what constitutes object equality for this particular class. In the example you provided, if you have two different objects that both have x=5, are they equal? It really depends on what you are trying to do.
您问题的一个同样重要的方面是如何正确实现 equals()。对此的答案实际上取决于构成该特定类的对象相等性的内容。在您提供的示例中,如果您有两个不同的对象,它们的 x=5,它们是否相等?这真的取决于你想要做什么。
If you are only interested in object equality, then the defaultimplementation of .equals() (the one provided by Object) uses identity only (i.e. this == other). If that's what you want, then just don't implement equals() on your class (let it inherit from Object). The code you wrote, while kind of correct if you are going for identity, would never appear in a real class b/c it provides no benefit over using the default Object.equals() implementation.
如果您只对对象相等性感兴趣,那么.equals()的默认实现(Object 提供的实现)仅使用标识(即 this == other)。如果这就是你想要的,那么就不要在你的类上实现 equals() (让它从 Object 继承)。您编写的代码虽然有点正确,但如果您要进行标识,则永远不会出现在真正的 b/c 类中,与使用默认的 Object.equals() 实现相比,它没有任何好处。
If you are just getting started with this stuff, I strongly recommend the Effective Java book by Joshua Bloch. It's a great read, and covers this sort of thing (plus how to correctly implement equals() when you are trying to do more than identity based comparisons)
如果你刚开始接触这些东西,我强烈推荐 Joshua Bloch 的 Effective Java 一书。这是一本很好的读物,涵盖了这类事情(以及当您尝试做的不仅仅是基于身份的比较时如何正确实现 equals())
回答by alexloh
Generally you should also override hashCode()
each time you override equals()
, even if just for the performance boost. HashCode()
decides which 'bucket' your object gets sorted into when doing a comparison, so any two objects which equal()
evaluates to true should return the same hashCode
value()
. I cannot remember the default behavior of hashCode()
(if it returns 0 then your code should work but slowly, but if it returns the address then your code will fail). I do remember a bunch of times when my code failed because I forgot to override hashCode()
though. :)
通常,您也应该在hashCode()
每次覆盖时覆盖equals()
,即使只是为了提高性能。HashCode()
决定在进行比较时您的对象被分类到哪个“桶”中,因此任何两个equal()
评估为 true 的对象都应该返回相同的hashCode
value()
. 我不记得的默认行为hashCode()
(如果它返回 0 那么你的代码应该可以运行但很慢,但是如果它返回地址那么你的代码将失败)。我确实记得有很多次我的代码失败了,因为我忘记了覆盖hashCode()
。:)
回答by Davide
class Thing {
public int value;
public Thing (int x) {
value = x;
}
equals (Thing x) {
if (x.value == value) return true;
return false;
}
}
You must write:
你必须写:
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;
}
}
Now it works ;)
现在它起作用了;)
回答by ChristopheCVB
I think that right implementations should be
我认为正确的实现应该是
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;
}
}
回答by Caner
Just wanted to note that the following implementation is wrong when value
is not a primitive type:
只是想注意,当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;
}
}
In that case I propose the following:
在这种情况下,我提出以下建议:
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;
}
}
回答by DenisKolodin
Shortcut from JavaDoc:
JavaDoc 的快捷方式:
booleancontains(Object o)
布尔值包含(对象 o)
Returns true if this list contains the specified element. More formally, returns true if and only if this list contains at least one element e such that (o==null ? e==null : o.equals(e))
如果此列表包含指定的元素,则返回 true。更正式地说,当且仅当此列表包含至少一个元素 e 使得(o==null ? e==null : o.equals(e))时才返回 true