2

所以我有这个代码:

List<MyDataType> test = map.get(id)
MyDataType test1 = new MyDataType("XXX", 1); 
System.out.println(test.contains(test1)); // returns false
System.out.println(test.get(0).equals(test1)); // returns true
System.out.println(test.remove(test1)); // returns false 
System.out.println(test); // still the original list

我已经重写了MyDataType中的.equalsand.hashCode()方法,而且是一致的。此外,mapis 类型ListMultimap<Long, DestQuanTuple>(忘记在我的 OP 中提及这一点。)但是,调用: map.remove(sourceContainerId, test1)也不会修改test

MyDataType班级:

public class MyDataType implements Comparable<MyDataType> {
    private String destination;
    private int quantity;

    // Constructor initializes destination and quantity

    // Getters exist to get destination and quantity

    public boolean equals (MyDataType other) {
        boolean destinationSame = false, quantitySame = false;
        destinationsame = this.getDestination().equals(other.getDestination());
        Integer thisQuantity = (Integer) this.getQuantity();
        Integer otherQuantity = (Integer) other.getQuantity();
        quantitySame = thisQuantity.equals(otherQuantity);
        return destinationSame && quantitySame;
    }

    public int hashCode() {
        return destination.hashCode() + quantity;
    }

    public int compareTo(MyDataType other) {
        Integer myQuantity = this.getQuantity();
        if (myQuantity.compareTo(other.getQuantity()) != 0) {
            return myQuantity.compareTo(otherTuple.getQuantity());
        }
        else {
            return this.getDestination().compareTo(otherTuple.getDestination());
        }
    }
}

知道为什么我没有得到我想要的功能吗?

4

3 回答 3

2

你遇到的问题是你必须定义equalshashCode一致

boolean contains(Object o)

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

合同是 a.equals(b), then a.hashCode() must be same as b.hashCode().

结论,你必须覆盖equalshashCode

更新

 public boolean equals (MyDataType other) {

 }

一定是,

 @Override
 public boolean equals (Object other) {

 }

请注意,如果您使用覆盖注释,那么如果您有错误将无法编译,因此请使用注释!

您正在重载等于这通常不是必需的,因为它很难维护,在您的情况下,意外行为成为导致集合使用默认值equals(Object o)的原因,这就是您拥有它的原因。

于 2013-06-28T01:12:03.653 回答
1

您没有覆盖该equals()方法,实际上是重载它。

更改签名 -

@Override
public boolean equals (Object other) {

以下是正在发生的事情 -

System.out.println(test.contains(test1)); // returns false

false 因为内部调用的方法是equals(Object obj).

System.out.println(test.get(0).equals(test1)); // returns true

true 因为您正在调用该方法equals(MyDataType other)

System.out.println(test.remove(test1)); // returns false 

false 因为内部调用的方法是equals(Object obj).

于 2013-06-28T01:47:39.830 回答
0

我假设测试应该包含值为 XXX 和 1 的 MyDataType?

如果是这样,您可能需要重写 MyDataType 的 equals() 方法,以便 List.Contains() 和 List.Remove() 在列表中找到 MyDataType。只有当 MyDataTypes 都指向内存中的同一个对象时,默认的 equals() 方法才会返回 true。

于 2013-06-28T01:12:10.130 回答