Пояснение для v-> v> 5 - PullRequest
       4

Пояснение для v-> v> 5

0 голосов
/ 09 января 2019

У меня есть заданный вызов функции, и Java выдает мне ошибку, потому что объекты не сравнимы с целыми числами (конечно ...). Может кто-нибудь объяснить мне, что я должен изменить?

Я пытался связать лямбда-выражение по-другому, но безрезультатно. Я думаю, что лямбда-выражение является правильным, а функция фильтра - немного неправильной, но я не могу обнаружить свою ошибку ...

// function call
filter(v -> v > 5)

// function
public Optional<T> filter(Predicate<T> tester) {
    if(isPresent() && tester.test(get())) {
        return this;
    } else {
    return Optional.empty();
    }
}

Я бы ожидал Optional.empty-Object, но я получаю java-ошибку, потому что v > 5 Object v не сопоставим с int.

Ответы [ 4 ]

0 голосов
/ 09 января 2019

v -> v > 5 может означать разные вещи. Это зависит от контекста.

  1. Это может быть (Object v) -> v > 5, вызывающее ошибку компиляции, поскольку > нельзя применить к Object:

    Stream.<Object>of("123", 123).filter(v -> v > 5);
    
  2. Это может быть (Integer v) -> v > 5, означающее, что распаковка и автобокс будут выполнены для сравнения и возврата результата:

    Stream.<Integer>of(123, 123).filter(v -> v > 5);
    
  3. Это может быть (int v) -> v > 5, означающее, что это экземпляр IntPredicate, и здесь все пройдет гладко:

    IntStream.of(123, 123).filter(v -> v > 5);
    
0 голосов
/ 09 января 2019

Вы должны сделать T классом-оболочкой, сравнимым с int. например,

IntStream.range(0, 10)
         .filter(v -> v > 5)
         .forEach(System.out::println);

хорошо, потому что v это int.

Вы не можете использовать это выражение, когда T неизвестно.

Что вы можете сделать, это предположить, что T должно быть числом, например,

filter( v -> ((Number) v).doubleValue() > 5)

однако это приведет к ClassCastExpection, если T - это другой тип.

Реальное решение состоит в том, чтобы сделать T a Number

* * 1 022, например,
class MyClass<T extends Number> {
    public Optional<T> filter(Predicate<T> test) {

или сделайте его конкретным типом, например int

class MyClass {
    public IntOptional filter(IntPredicate test) {
0 голосов
/ 09 января 2019

Я думаю, что лямбда-выражение правильно и функция фильтра немного неправильная, но я не могу выяснить ошибка ...

Вы правы.
Ваш метод, кажется, побеждает универсальный тип, объявленный для класса, поскольку в первую очередь ваш метод определен внутри универсального класса.

Предположим, что ваш класс назван Foo, здесь метод filter() использует общий тип T в качестве типа возврата / параметра:

public class Foo<T>{
     // ...
    public Optional<T> filter(Predicate<T> tester) { 
      // ...
    }
}

Работает с выводом.
Таким образом, вы получаете Predicate из T. Но T зависит от универсального типа, определенного в классе, а также от способа, которым вы объявили экземпляр класса Foo.
И похоже, что здесь T не является Number.

В качестве альтернативы вы также можете рассчитывать на вывод из объявленной переменной Foo.
Если вы сделаете это:

Foo<Integer> foo = new Foo<>();
Optional<Integer> optInt = foo.filter(v -> v > 5);

будет компилироваться нормально, так как Integer будет выведено из Foo<Integer>.

Так что я думаю, что для решения вашей проблемы вы должны объявить Number или Integer в качестве базового класса универсального типа:

public class Foo<T extends Integer>{
     // ...
    public Optional<T> filter(Predicate<T> tester) { 
      // ...
    }
}

или полагаться на вывод клиента, как в предыдущем примере.

0 голосов
/ 09 января 2019

В примитивах Java типы (например, int) и объекты (например, Object) не имеют общего предка в иерархии типов. Благодаря этому предикаты и другие потоковые конструкции бывают двух видов, например: IntPredicate необходимо использовать при работе с int и Predicate, которые необходимо использовать при работе с Object.

При написании вашей функции фильтра можно использовать OptionalInt и IntPredicate:

public OptionalInt filter(IntPredicate tester) {
    if (isPresent() && tester.test(get())) {
        return ...
    } else {
        return OptionalInt.empty();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...