Лямбда как комбинация методов из интерфейса Predicate не компилируется, если она записана как один оператор - PullRequest
0 голосов
/ 03 мая 2018

В чем разница между этими двумя способами создания лямбды? Почему первый не компилируется?

Predicate<Integer> predicate = Predicate.isEqual(0).or(Predicate.isEqual(1));

Дает: ошибка : несовместимые типы: Predicate<Object> невозможно преобразовать в Predicate<Integer> = Predicate.isEqual(0).or(Predicate.isEqual(1));

Predicate<Integer> pred21 = Predicate.isEqual(0);
Predicate<Integer> pred22 = pred21.or(Predicate.isEqual(1));

Этот работает.

Ответы [ 4 ]

0 голосов
/ 03 мая 2018

Проблема связана с тем, как вывод работает в Java: это зависит от цели.

Здесь:

Predicate<Integer> predicate = Predicate.isEqual(0)
                                        .or(Predicate.isEqual(1));

Тип, возвращаемый or(Predicate.isEqual(1)), зависит от типа, возвращаемого Predicate.isEqual(0) (ближайшей целью), но этот вызов не указывает какой-либо другой тип в качестве возвращаемого.
Так Object возвращается or(Predicate.isEqual(1)) как метод isEqual() определяет T как тип возвращаемого значения без подстановочных знаков:

static <T> Predicate<T> isEqual(Object targetRef) {

Чтобы решить вашу проблему, вам действительно нужно указать тип возврата первого вызова, чтобы позволить цепочечному вызову вывести правильный тип: Integer.

Predicate<Integer> predicate = Predicate.<Integer>isEqual(0)
                                        .or(Predicate.isEqual(1));
0 голосов
/ 03 мая 2018

Это происходит потому, что

Predicate.isEqual(0)

имеет эту подпись:

static <T> Predicate<T> isEqual(Object targetRef)

Это выводит Predicate<Object>, если вы не наберете его.

Чтобы ввести его, вы можете ввести тип возврата

Predicate<Integer> pred21 = Predicate.isEqual(0);

Или наберите звонок как

Preicate.<Integer>isEqual
0 голосов
/ 03 мая 2018

Посмотрите на подпись:

 static <T> Predicate<T>    isEqual​(Object targetRef)

В первом примере компилятор не может угадать параметр универсального типа, поэтому он возвращает Predicate<Object>.

Правильный способ ввести его в одну строку - указать параметр типа, например

Predicate<Integer> predicate = Predicate.<Integer>isEqual(0).or(Predicate.isEqual(1));
0 голосов
/ 03 мая 2018

Добавление <Integer> перед вызовом метода isEqual должно помочь:

Predicate<Integer> predicate = Predicate.<Integer>isEqual(0).or(Predicate.isEqual(1));

Причина такого поведения компилятора:

  • isEqual - это статический обобщенный метод, который возвращает Predicate<T> (независимо от того, какой фактический тип его входного параметра), поэтому он возвращает Predicate<Object> при вызове метода без явного указания возвращаемого типа.
  • or также является статическим универсальным методом, но он возвращает предикат, параметризованный тем же типом, что и его входной параметр (который является Predicate<Object>).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...