tl; dr:
Прежде всего вы должны знать, что Predicate - это не класс, а interface .А лямбды - это почти анонимные классы (с небольшими отличиями, которые не важны в контексте вашего вопроса).Таким образом, все ваши три функции, которые вы указали в своем вопросе, возвращают объекты, которые являются экземплярами трех разных классов (конечно, все они реализуют один и тот же интерфейс, поэтому вы можете использовать все из них в качестве ключей в Map).Но карта (которая на самом деле тоже интерфейс, поэтому вам нужно понять, как работает точная реализация карты, которую вы используете в своем коде) обычно используют equals (), hashCode () и иногда может быть CompareTo () вашего ключевого класса.И поскольку вы используете анонимные классы (строго: «почти анонимные классы»), он использует equals () и hashCode () из класса Object.Где hashCode () не зависит от методов объекта и данных, но создан JRE и equals () сравнивает хеш-коды.
Кратко:
Неиспользуйте анонимные (объявленные как лямбда) предикаты в качестве ключей на вашей карте.Создайте свой собственный класс, который реализует интерфейс Predicate и имеет собственную реализацию hashCode (), equals () и test ().Если вы все еще хотите использовать лямбда-выражения, используйте эти анонимные предикаты в качестве поля вашего собственного ключевого класса.
Обычно:
Чтобы избежать таких проблем, просто рассматривайте лямбда-выражения в java какСинтаксический сахар (лямбда - это не просто синтаксический сахар, а почти синтаксический сахар).Когда вы пишете код:
Predicate<String> aPredicate= s->"asd".equals(s);
рассматривайте его как специальную форму кода ниже:
Predicate<String> aPredicate= new Predicate<String>() {
@Override
public boolean test(String s) {
return "asd".equals(s);
}
};