什么不可变对象适用于 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
.
我想创建一个坐标列表并能够检查该列表是否包含新坐标。
我已经尝试实现 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
.