Вероятно, это связано с тем, что ваша реализация 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
использует равенство объектов в качестве теста (метод по умолчанию equals
в классе Object
). Например, в приведенном выше коде 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
.