Java ArrayList';s contains()方法计算对象?
假设我创建了一个对象并将其添加到我的Java ArrayList';s contains()方法计算对象?,java,object,arraylist,evaluation,Java,Object,Arraylist,Evaluation,假设我创建了一个对象并将其添加到我的ArrayList。如果我随后使用完全相同的构造函数输入创建另一个对象,那么contains()方法会将这两个对象计算为相同的吗?假设构造函数对输入没有做任何有趣的事情,并且存储在两个对象中的变量是相同的 ArrayList<Thing> basket = new ArrayList<Thing>(); Thing thing = new Thing(100); basket.add(thing); Thing anothe
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?
这就是
类
应该如何实现以使contains()
返回true
?ArrayList使用类(您的案例对象类)中实现的equals方法来进行equals比较。它对对象使用equals方法。因此,除非Thing覆盖等于并使用存储在对象中的变量进行比较,否则它在contains()
方法上不会返回true。ArrayList实现列表接口
如果您查看at thecontains
方法,您将看到它使用equals()
方法来评估两个对象是否相同。其他海报已经解决了contains()如何工作的问题
您的问题的一个同样重要的方面是如何正确地实现equals()。这个问题的答案实际上取决于什么构成了这个特殊类的对象相等性。在您提供的示例中,如果有两个x=5的不同对象,它们是否相等?这真的取决于你想做什么
如果您只对对象相等感兴趣,那么.equals()的默认实现(由object提供的)只使用标识(即this==other)。如果这是您想要的,那么就不要在类上实现equals()(让它从对象继承)。虽然您编写的代码在某种程度上是正确的,但如果您使用的是identity,它将永远不会出现在实际的b/c类中。与使用默认的Object.equals()实现相比,它没有任何好处
如果您刚刚开始学习这些东西,我强烈推荐Joshua Bloch的《有效的Java》一书。这是一本很棒的读物,涵盖了这类内容(以及当您尝试进行基于身份的比较时如何正确实现equals())通常,每次重写equals()
时,您也应该重写hashCode()
,即使只是为了提高性能HashCode()
决定在进行比较时将对象排序到哪个“bucket”,因此equal()
计算结果为true的任何两个对象都应返回相同的HashCode
值()。我记不起hashCode()
的默认行为(如果它返回0,那么代码应该运行缓慢,但如果它返回地址,那么代码将失败)。我确实记得有很多次我的代码失败,因为我忘记重写hashCode()
。)
你必须写:
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;
}
}
现在它起作用了;) 我认为正确的实现应该是
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;
}
}
只是想注意,当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;
}
}
在这种情况下,我提议如下:
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;
}
}
快捷方式来自:
布尔值包含(对象o)
如果此列表包含指定的元素,则返回true。更正式地说,
当且仅当此列表至少包含一个元素e时返回true
(o==null?e==null:o.equals(e))记录
覆盖等于
你说:
另一个具有完全相同构造函数输入的对象
……还有
假设构造函数对输入没有做任何有趣的事情,并且存储在两个对象中的变量是相同的
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?
正如其他答案所解释的,您必须覆盖要工作的方法
在+,该功能会自动为您覆盖该方法
记录是编写类的一种简单方法,其主要目的是以透明和不变的方式传输数据。默认情况下,只需声明成员字段。编译器隐式地创建构造函数、getter、equals
&hashCode
和toString
默认情况下,equals
的逻辑是将一个对象的每个成员字段与同一类的另一个对象中的对应字段进行比较。同样,“代码> > HASCODE 和ToSoS 方法的默认实现也考虑每个成员字段。
记录事物(整数金额){};
就是这样,这就是一个功能完整的只读类所需的全部代码,而不需要任何常规的代码
示例用法
thingx=新事物(100);
事物y=新事物(100);
布尔奇偶校验=x.equals(y);
跑步的时候
奇偶校验=真
回到你的问题上来
thingx=新事物(100);
列出事物=
名单(
新事物(100),
新事物(200),
新事物(300)
);
布尔foundX=things.contains(x);
跑步的时候
foundX=true
额外功能:记录可以在方法中本地声明。或者像传统的类一样,您可以将记录声明为嵌套类或单独的类。出于我的目的,我试图查看ArrayList中是否有一个值相等的对象。我想这是一种黑客行为。感谢您的推荐书。如果您计划重写equals(),请确保重写hashcode()方法。如果您不愿意,则在使用集合时可能无法按预期工作?这是一个正确答案,但请注意,您需要更改equals方法以接受对象,而不是对象。如果不这样做,将不会使用equals方法。:)我刚刚发现eclipse在源代码菜单下有“Generate hashCode()and equals”,这回答了标题中的问题,但没有回答描述中的问题,即“如果我
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;
}
}