什么不可变对象适用于 List.contains?

What immutable object works with List.contains?

我想创建一个坐标列表并能够检查该列表是否包含新坐标。

我已经尝试实现 Pair,但是使用 List.contains()Pair 不起作用,总是返回 false。

我可以使用哪些其他对象来检查 List.contains()

我认为您的 Pair 包含相同的值,但对象不同。那是因为它不起作用。您可以改用地图。

How you can use a map:

Map<String, Integer> map = new HashMap<>();
map.put("Hello", 0); // add key an value to map (Key: "Hello", Value: 0)
map.put("World", 1); // add key an value to map (Key: "World", Value: 1)

if (map.containsKey("World")) { // check if map contains key: "World"
  System.out.println(map.get("World")); // try return value by key: returns 1
  System.out.println(map.get("world")); // try return value by key: returns null
}

if (map.containsKey("Hello")) { // check if map contains key: "Hello"
  System.out.println(map.get("Hello")); // try return value by key: returns 0
  System.out.println(map.get("hello")); // try return value by key: returns null
}

List.contains 使用 Object.equals 方法检查两个对象是否相等。因此,它仅适用于实现了 Object.equals 方法的对象。如果您正在编写自己的 Pair class,请确保为其提供 equals 方法。

这可能是因为您的 Pair 实现没有提供重写的 equals 方法。我能够使用以下代码重现您的问题:

//a plain POJO, in Pair.java
public class Pair<A, B> {
    private A a;
    private B b;

    public Pair(A a, B b) {
        this.a = a;
        this.b = b;
    }

    public A getA() {
        return a;
    }

    public B getB() {
        return b;
    }
}

//... Main.java

public class Main {
    public static void main(String[] args) {
        List<Pair<Integer, String>> list = new ArrayList<>();
        Pair<Integer, String> one = new Pair<>(1, "hello");
        Pair<Integer, String> two = new Pair<>(1, "hello");
        list.add(one);
        System.out.println(list.contains(two));
    }
}

这会打印出 false,因为 List.contains 使用对象相等性作为测试(class Object 中的默认 equals 方法)。例如,对于上面的代码,one.equals(two) 的计算结果为 false,因为它们不是同一个对象。要解决此问题,您必须提供一个 equals 方法来查看每个字段并单独比较它们:

//in class Pair
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Pair<?, ?> pair = (Pair<?, ?>) o;
    return Objects.equals(a, pair.a) &&
            Objects.equals(b, pair.b);
}

您可以将编写此代码的有点繁琐且容易出错的任务委托给您的 IDE。我正在使用 Intellij,只需单击 Code/Generate/equals() and hashcode() 即可。对于这种特殊情况,您不需要 hashcode(),但将 equals()hashcode() 放在一起总是一个好主意。现在,当 List.contains 尝试查找与您提供的元素相同的元素时,它将使用这种新的更合适的方法。如果您再次 运行 main 方法,您会看到它的计算结果为 true.