Проверка равенства между параметризованным предикатом - PullRequest
0 голосов
/ 28 ноября 2018

В настоящее время я реализую способ сопоставления предиката с текстовой строкой

Для этого сопоставления я заполняю карту , а затем могу получить соответствующую строку с помощью предиката.

Проблема в том, что при использовании параметризованного предиката, как в коде ниже, одинаковое совпадение предикатов для разных параметров (valueToTest не используется в функции хеширования)

public static Predicate<MyObject> predicateCondition(String valueToTest) {
    return myObject -> myObject.value.equals(valueToTest);
}

Так что в настоящее время мне нужночтобы сделать один предикат для параметра, который я хотел бы проверить, то есть:

public static Predicate<MyObject> predicateConditionValue1() {
    return myObject -> myObject.value.equals("value1");
}

public static Predicate<MyObject> predicateConditionValue2() {
    return myObject -> myObject.value.equals("value2");
}

Был бы другой способ избежать дублирования предиката?

Ответы [ 3 ]

0 голосов
/ 28 ноября 2018

Чтобы избежать дублирования предикатов, вы должны использовать BiPredicate<T,U>, который принимает еще один параметр и также выдает Boolean.

BiPredicate<MyObject, String> biPredicate = (obj, string) -> myObject.value.equals(string)

В методе:

public static BiPredicate<MyObject, String> predicateConditionValue() {
     return (myObject, string) -> myObject.value.equals(string);
}
0 голосов
/ 28 ноября 2018

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);
            }
        };
0 голосов
/ 28 ноября 2018

В качестве альтернативы вы можете использовать BiFunction вместо:

BiFunction<MyObject, String, Boolean> isEquslTo = (myObject, expected) -> Objects.equals(myObject.value, expected);

Но мне нравятся подходы с двумя Predicate больше.

...