Java Collection.contains产生错误的结果

Java Collection.contains产生错误的结果,java,android,collections,Java,Android,Collections,我有一个对象,它有两个字段——正如您所看到的,hashcode和equals方法是在考虑id的情况下实现的: public class SpotResponse{ String id; // bla bla other fields public SpotResponse() { } public SpotResponse(@NonNull String id) { this.id = id; } public String getId() { return id; } @O

我有一个对象,它有两个字段——正如您所看到的,hashcode和equals方法是在考虑id的情况下实现的:

public class SpotResponse{
String id;
// bla bla other fields
public SpotResponse() {
}

public SpotResponse(@NonNull String id) {
    this.id = id;
}
public String getId() {
    return id;
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;

    SpotResponse that = (SpotResponse) o;

    return id == that.id;
}

@Override
public int hashCode() {
    return id.hashCode();
}
}
我有一个方法可以检查一个
集合是否有新闻点

包含来自
HashMap spots=new HashMap()的一些
oldSpot
s;

如果我这样做:

List<String> newKeys = new ArrayList<>();

    for (SpotResponse response : newSpots) {
        newKeys.add(response.getId());
    }

    for (SpotResponse oldSpot : spots.values()) {
        if (newKeys.contains(oldSpot.getId())) {
            continue;
        }
        /* blabla */
    }

它总是返回false。在这种情况下,集合是一个ArrayList(如果这有帮助的话)

在将Contains与原语一起使用时,必须小心。 从技术上讲,String是一个包含字符原语的对象类,但是当您比较它时,它不是比较文本对象内存指针,而是比较内存指针处的值

Contains在后台使用.equals,因此当在类中重写equals时,不能默认返回==比较,因为它比较的是地址,而不一定是值


希望这能有所帮助。

在原语中使用Contains时必须小心。 从技术上讲,String是一个包含字符原语的对象类,但是当您比较它时,它不是比较文本对象内存指针,而是比较内存指针处的值

Contains在后台使用.equals,因此当在类中重写equals时,不能默认返回==比较,因为它比较的是地址,而不一定是值


希望这能有所帮助。

您的bug在
equals
实现中,在这一行:

return id == that.id;

当您应该使用
id.equals(that.id)
时,您正在比较两个
String
字符串(即
id
that.id
)与
=
,您的bug在
equals
实现中,在这一行:

return id == that.id;

您正在比较两个
字符串(即
id
that.id
)与
=
,此时您应该使用
id.equals(that.id)

,这是因为您没有向新闻点添加任何内容。你在增加newKeys@Kwright02新闻点已经包含了一些有效负载,我只是不比较字符串id,而是依赖于实际SpotResponse对象之间的比较。什么是新闻点的数据类型?也可能重复,不要使用
other.getClass()==getClass()
比较对象。可能有某些原因(例如JPA)将其子类化,但仍应将其视为相等。改用
instanceof
。这是因为您没有向新闻稿添加任何内容。你在增加newKeys@Kwright02新闻点已经包含了一些有效负载,我只是不比较字符串id,而是依赖于实际SpotResponse对象之间的比较。什么是新闻点的数据类型?也可能重复,不要使用
other.getClass()==getClass()
比较对象。可能有某些原因(例如JPA)将其子类化,但仍应将其视为相等。改为使用
instanceof
。“compareTo(“String”)==0”与
equals
有什么问题?这个答案是错误的<代码>包含
使用对象的
等于
方法正确检查对象的相等性。这不仅仅是比较内存指针。比较可以有空点异常,如果一方为空,则equals将不会。同样,equals执行一个“实例”调用,该调用需要稍多的时间performance@Sam那完全不是重点。您的语句“contains正在比较内存指针,就像此数组是否包含此内存指针”是错误的
包含
检查是否存在与搜索对象相等的元素。
等于
。“compareTo”(“字符串”)==0”与
等于
有什么问题?此答案错误<代码>包含使用对象的
等于
方法正确检查对象的相等性。这不仅仅是比较内存指针。比较可以有空点异常,如果一方为空,则equals将不会。同样,equals执行一个“实例”调用,该调用需要稍多的时间performance@Sam那完全不是重点。您的语句“contains正在比较内存指针,就像此数组是否包含此内存指针”是错误的<代码>包含检查是否存在与搜索对象相等的元素。