Java ArrayList Contain 总是返回 false,尽管它包含相同的值

Posted

技术标签:

【中文标题】Java ArrayList Contain 总是返回 false,尽管它包含相同的值【英文标题】:Java ArrayList Contain always return false although it contain the same value 【发布时间】:2014-01-18 12:41:48 【问题描述】:

这是我的洞课

class Hole 

public  int a;
public  int b;

Hole(int a, int b) 
    this.a = a;
    this.b = b;

所以我添加了一个包含几个孔的 ArrayList

public void checkPathLoop(int x, int y) 
        //rough code

        ArrayList<Hole> leftFlowInnerHole = new ArrayList<>();


        //left holes rules
        leftFlowInnerHole.add(new Hole(0, 1));
        leftFlowInnerHole.add(new Hole(1, 5));
        leftFlowInnerHole.add(new Hole(5, 4));
        leftFlowInnerHole.add(new Hole(0, 4));

当我添加时

Hole userInputHole = new Hole(0,1);
System.out.print(leftFlowInnerHole.contain(userInputHole));

它总是返回 false !它应该返回true。

有什么我想念的吗?

提前谢谢你

【问题讨论】:

【参考方案1】:

这不行

   if(priceidslist.contains(extraId))
                               //Not working 
                            

我刚刚添加了这行来检查(for -loop)中的条件,然后它工作正常

  String gh = String.valueOf(priceidslist.get(j));
                           if(gh.equals(extraId))
                               rw.put("extraPrice",pricelist.get(j));
                           

【讨论】:

【参考方案2】:

你应该覆盖 Hole 类的 equals 方法:

@Override
public boolean equals(Object obj) 

if (obj == this) 
    return true;


if (!(obj instanceof Hole)) 
    return false;


Hole other = (Hole) obj;

return a == other.a && b == other.b;

【讨论】:

【参考方案3】:

contains() 方法在检查时检查 Object 上的 equal() 方法。

您必须覆盖 equals 方法才能使其工作。

public boolean contains(Object o)

如果此列表包含指定元素,则返回 true。更正式地说,当且仅当此列表包含至少一个元素 e 满足 (o==null ? e==null : o.equals(e)) 时才返回 true。

Edit:

如果您不使用 equals 方法,则默认执行 Object 的 equals 方法,并且根据 Equals 方法的文档

Object 类的 equals 方法实现了对象上最有区别的可能等价关系;也就是说,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象(x == y 的值为 true)时,此方法才返回 true。 p>

所以你的userInputHole == leftFlowInnerHole 总是错误的,因为它们指向不同的实例。

因此,为了避免默认实现,您只需在您的类中覆盖 equals 并提供您的实现。

An efficient equals(Object o) implementation

【讨论】:

这种情况下不执行equals()默认实现吗? 为什么是假的(因为默认实现使用 == 进行比较)?这是答案中缺少的一点。【参考方案4】:

您需要在您的Hole 类中重写从Object 类继承的equals 方法(因此还要遵守hashCode 的约定,请参阅Why do I need to override the equals and hashCode methods in Java?)。

如果此列表包含指定元素,则返回 true。更多的 正式地,当且仅当此列表包含至少一个时才返回 true 元素 e 使得 (o==null ? e==null : o.equals(e))。

基本上默认的equals实现是两个对象之间的==比较

public boolean equals(Object obj) 
   return (this == obj);

由于您创建了两个不同的对象,虽然它们与属性具有相同的值,但它们是两个不同的对象,因此this == obj 返回false

如果你这样做了:

Hole a = new Hole(0,1);
leftFlowInnerHole.add(a);
System.out.print(leftFlowInnerHole.contains(a));

你会看到它输出了true

【讨论】:

以上是关于Java ArrayList Contain 总是返回 false,尽管它包含相同的值的主要内容,如果未能解决你的问题,请参考以下文章

带有 ArrayList 的 Java for 循环

Java 中的 List —— 有序序列

java ArrayList循环增加add(对象)总是被最后一个覆盖,把new 对象放在循环里面也是,求大神帮忙

Mac上解决dose not contain the JNI_CreateJavaVM symbol

Mac上解决dose not contain the JNI_CreateJavaVM symbol

java源码只集合类ArrayList