Rei*_*Mac 27 java contains equals
我有一个问题,我创建一个Foo对象的ArrayList,我重写equals方法,我不能让contains方法调用equals方法.我已经尝试重写equals和hashcode,但它仍然无法正常工作.我敢肯定有一个合乎逻辑的解释,为什么会这样,但我现在无法弄清楚我自己大声笑.我想要一种方法来查看列表是否包含指定的id.
这是一些代码:
import java.util.ArrayList;
import java.util.List;
public class Foo {
private String id;
public static void main(String... args){
Foo a = new Foo("ID1");
Foo b = new Foo("ID2");
Foo c = new Foo("ID3");
List<Foo> fooList = new ArrayList<Foo>();
fooList.add(a);
fooList.add(b);
fooList.add(c);
System.out.println(fooList.contains("ID1"));
System.out.println(fooList.contains("ID2"));
System.out.println(fooList.contains("ID5"));
}
public Foo(String id){
this.id = id;
}
@Override
public boolean equals(Object o){
if(o instanceof String){
String toCompare = (String) o;
return id.equals(toCompare);
}
return false;
}
@Override
public int hashCode(){
return 1;
}
}
Run Code Online (Sandbox Code Playgroud)
输出:false false false
Tom*_*icz 45
这是因为你equals()是不是对称的:
new Foo("ID1").equals("ID1");
Run Code Online (Sandbox Code Playgroud)
但
"ID1".equals(new Foo("ID1"));
Run Code Online (Sandbox Code Playgroud)
不是真的.这违反了equals()合同:
equals方法在非null对象引用上实现等价关系:
[...]
它是对称的:对于任何非空引用值
x和y,x.equals(y)应真,当且仅当返回y.equals(x)的回报true.
这也不是反身:
- 它是自反的:对于任何非空引用值
x,x.equals(x)应该返回true.
Foo foo = new Foo("ID1");
foo.equals(foo) //false!
Run Code Online (Sandbox Code Playgroud)
@mbockus提供了正确的实现equals():
public boolean equals(Object o){
if(o instanceof Foo){
Foo toCompare = (Foo) o;
return this.id.equals(toCompare.id);
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
但现在你必须将实例传递Foo给contains():
System.out.println(fooList.contains(new Foo("ID1")));
System.out.println(fooList.contains(new Foo("ID2")));
System.out.println(fooList.contains(new Foo("ID5")));
Run Code Online (Sandbox Code Playgroud)
最后,您应该实现hashCode()以提供一致的结果(如果两个对象相等,它们必须相等hashCode()):
@Override
public int hashCode() {
return id.hashCode();
}
Run Code Online (Sandbox Code Playgroud)
Mik*_*kus 11
您的equals方法需要更改,同时覆盖hashCode()函数.目前,当您需要检查Foo对象时,您正在检查您要比较的对象是否是String的实例.
public boolean equals(Object o){
if(o instanceof Foo){
Foo toCompare = (Foo) o;
return this.id.equals(toCompare.id);
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
如果您正在使用Eclipse,我建议让Eclipse生成hashCode并通过转到Source - > Generate hashcode()和equals()来等于你...
你应该实现hashCode
@Override
public int hashCode() {
return id.hashCode();
}
Run Code Online (Sandbox Code Playgroud)
即使包含在没有它的ArrayList中.你的大问题是你的equals需要String,而不是Foo对象以及你要求包含字符串.如果实现询问列表中的每个弹出是否等于你发送的字符串,那么你的代码可以工作,但是实现会询问字符串是否等于你的Foo目标,当然它不是.
使用等于
@Override
public boolean equals(Object o){
if(o instanceof Foo){
String toCompare = ((Foo) o).id;
return id.equals(toCompare);
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
然后检查包含
System.out.println(fooList.contains(new Foo("ID1")));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
55564 次 |
| 最近记录: |