ошибка: несовместимые типы: неожиданное возвращаемое значение: Java 8 - программирование
Подтвердить что ты не робот

ошибка: несовместимые типы: неожиданное возвращаемое значение: Java 8

Я написал простой метод, который возвращает логическое значение.

private boolean isActionAvailable(Collection<StudentConfiguration> studentConfigs){
       if(studentConfigs != null)
        {
            studentConfigs.forEach(studentConfig -> {
                if(studentConfig.action() == null || !studentConfig.action().equals(Action.DELETE)) {
                    return true;
                }
            });
        }
        return false;
    }

Метод выдает следующее исключение.

error: incompatible types: unexpected return value
            studentConfigs.forEach(studentConfig -> 

В чем проблема с моим кодом?

4b9b3361

Ответ 1

Лямбда-выражение, переданное в forEach не должно иметь возвращаемого значения.

Похоже, вы хотите вернуть true если какой-либо из элементов входной Collection удовлетворяет условию:

private boolean isActionAvailable(Collection<StudentConfiguration> studentConfigs){
    if(studentConfigs != null) {
        if (studentConfigs.stream().anyMatch(sc -> sc.action() == null || !sc.action().equals(Action.DELETE))) {
            return true;
        }
    }
    return false;
}

Как предположил Хольгер, это можно свести к одному утверждению:

return studentConfigs != null && studentConfigs.stream().anyMatch(sc -> sc.action() == null || !sc.action().equals(Action.DELETE));

или же

return studentConfigs != null ? studentConfigs.stream().anyMatch(sc -> sc.action() == null || !sc.action().equals(Action.DELETE)) : false;

Ответ 2

В качестве альтернативы с Java9 и выше вы можете использовать Stream.ofNullable и обновлять как:

private boolean isActionAvailable(Collection<StudentConfiguration> studentConfigs) {
    return Stream.ofNullable(studentConfigs)
            .flatMap(Collection::stream)
            .anyMatch(studentConfig -> studentConfig.action() == null || !studentConfig.action().equals(Action.DELETE));
}

Ответ 3

Я не рекомендую вам использовать Stream API здесь. Посмотрите, насколько ясна и проста версия foreach:

private boolean isActionAvailable(Collection<StudentConfiguration> studentConfigurations) {
    if(studentConfigurations == null) {
        return false;
    }

    for (StudentConfiguration configuration : studentConfigurations) {
        if (!Action.DELETE.equals(configuration.action())) {
            return true;
        }
    }

    return false;
}

В противном случае, если вы фанатик,

private boolean isActionAvailable(Collection<StudentConfiguration> configs) {
    return configs != null &&
           configs.stream()
                  .map(StudentConfiguration::action)
                  .anyMatch(Predicate.isEqual​(Action.DELETE).negate()));
}

Ответ 4

Оператор return в вашей isActionAvailable() прекратит эту лямбду, а не метод isActionAvailable(). Следовательно, предполагаемый тип лямбды теперь неверен, потому что forEach ожидает Consumer.

Посмотрите другие ответы о том, как решить эту проблему.

Ответ 5

Это подпись метода forEach() для forEach(Consumer<? super T> action).
Он принимает ссылку на интерфейс Consumer, который имеет метод void accept(T t). В вашем коде вы переопределяете accept() и возвращаете значение, которое недопустимо, поскольку accept() имеет тип возврата void.
Поэтому он показывает ошибку

 error: incompatible types: unexpected return value
            studentConfigs.forEach(studentConfig ->