为什么包含值返回false?

时间:2014-08-22 12:57:21

标签: java collections treemap

请不要介意我的常规错误

class test implements Comparable<test>
{
    int id;
    String name;
    public test(int id,String name)
    {
        this.id=id;
        this.name=name;
    }

    @Override
    public int compareTo(test o) {
        if(this.id>o.id)
            return 1;
        else if(this.id==o.id)
            return 0;
        else
            return -1;

    }
}
class le
{
    public static void main(String[] args) {
        TreeMap<test,test> p=new TreeMap<test,test>();
        p.put(new test(1,"sad"), new test(3121, "adweq"));
        p.put(new test(2, "asds"),new test(3123,"awdq"));
        p.put(new test(23,"akjdb"),new test(23123,"dqWQDD"));
        Set<Map.Entry<test,test>> s=p.entrySet();
        Iterator <Map.Entry<test, test>> i=s.iterator();
        while(i.hasNext())
        {
            Map.Entry<test, test> m=i.next();
            System.out.println(m.getKey().id);
            System.out.println(m.getValue().name);
        }
        System.out.println(p.containsKey(new test(1,"sad")));//returning true
        System.out.println(p.containsValue(new test(3123,"awdq")));//why it is returning false
    }   
}

这里我已经制作了一个树形图,并且想知道为什么在containsvalue方法中它返回false?而我已经实现了类似的界面&gt;

3 个答案:

答案 0 :(得分:2)

因为您的课程test未覆盖equals()hashCode(),所以

@Override
public boolean equals(Object o) {
  if (o instanceof test) {
    test t = (test) o;
    return t.id == o.id;
  }
  return false;
}
@Override
public int hashCode() {
  return Integer.valueOf(id).hashCode();
}

假设id相等就足够了。此外,test是一个糟糕的类名。 Java命名约定是Test,但这也是一个糟糕的名字。也许,EqualityTest(所以它有一些含义)。

答案 1 :(得分:2)

您需要覆盖Object.equals课程中的Test,以检查new test(3123,"awdq")new test(3123,"awdq")的另一个实例之间是否相等。

建议在覆盖Object.hashCode时覆盖equals

答案 2 :(得分:2)

compareTo()方法还不够 - 您需要实施equals()方法(建议您在覆盖hashCode()时覆盖equals())。方法如下:

class test implements Comparable<test>
{
    int id;
    String name;
    public test(int id,String name)
    {
        this.id=id;
        this.name=name;
    }

    @Override
    public int compareTo(test o) {
        if(this.id>o.id)
            return 1;
        else if(this.id==o.id)
            return 0;
        else
            return -1;

    }

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

      test that = (test) o;
      return this.compareTo(that) == 0;
    }

    @Override
    public int hashCode() { return id; }
}

旁注 为什么equals()使用getClass().equals(o.getClass())而不是(o instanceof test)

让我们假设有一个名为test2的测试类的子类,而t1和t2是test,test2(分别)类型的对象。

如果test2覆盖了equals(),那么t1.equals(t2)如果使用t2.equals(t1)实现了equals(),则instanceof会产生与equals()不同的结果。这违反了{{1}}合同(具体而言,是对称要求)。