Когда скобки необязательны в лямбда-синтаксисе Java 8?

java lambda java-8

7218 просмотра

5 ответа

3964 Репутация автора

Я понимаю, что лямбда-реализация Java 8 подвержена изменениям, но в лямбда-сборке b39 я обнаружил, что фигурные скобки можно опускать только тогда, когда лямбда-выражение возвращает тип, отличный от void. Например, это компилирует:

public class Collections8 {
        public static void main(String[] args) {
                Iterable<String> names = Arrays.asList("Alice", "Bob", "Charlie");
                names.filter(e -> e.length() > 4).forEach(e -> { System.out.println(e); });
        }
}

Но удаление скобок так:

names.filter(e -> e.length() > 4).forEach(e -> System.out.println(e));

выдает ошибку

Collections8.java:6: error: method forEach in interface Iterable<T> cannot be applied to given types;
        names.filter(e -> e.length() > 4).forEach(e -> System.out.println(e));
                                         ^
  required: Block<? super String>
  found: lambda
  reason: incompatible return type void in lambda expression
  where T is a type-variable:
    T extends Object declared in interface Iterable

Кто-нибудь может объяснить, что здесь происходит?

Автор: hertzsprung Источник Размещён: 21.06.2012 07:49

Ответы (5)


21 плюса

2922 Репутация автора

Решение

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

Если тело лямбда является блоком операторов (например, серия вычислений, за которым следует returnоператор), или лямбда не имеет значения (т. Е. Имеет voidтип возврата) и не является вызовом одного метода void, вы должны использовать этот блок форма, которая требует скобки.

В лямбде блочного стиля, если значение равно returned, то все возможные пути кода должны быть либо returnзначением, либо throwa Throwable.

Автор: jpm Размещён: 21.06.2012 08:10

11 плюса

10545 Репутация автора

Это только в: EG (в основном) принял решение о синтаксисе.

После рассмотрения ряда альтернатив мы решили по существу принять синтаксис C #. Мы можем еще обсудить тонкости (например, тонкая стрелка против жирной стрелки, специальная нулевая форма и т. Д.) И еще не приняли решение о синтаксисе ссылки на метод.

Синтаксис C #:

lambda = ArgList Arrow Body
ArgList = Identifier
           | "(" Identifier [ "," Identifier ]* ")"
           | "(" Type Identifier [ "," Type Identifier ]* ")"
Body = Expression
           | "{" [ Statement ";" ]+ "}"

Выражение что-то оценивает, вы не можете иметь пустые выражения в Java. Это утверждение, поэтому вам нужно {}вокруг него.

http://mail.openjdk.java.net/pipermail/lambda-dev/2011-September/003936.html

Автор: Ishtar Размещён: 21.06.2012 08:15

1 плюс

39 Репутация автора

Если фигурных скобок нет, лямбда автоматически возвращает одно выражение после оператора ->.
Таким образом, когда у вас есть лямбда, которая ничего не возвращает, вы должны использовать фигурные скобки

Автор: cuddlebugCuller Размещён: 08.04.2013 03:58

1 плюс

361 Репутация автора

Я попробовал ваш код и для самой последней версии JRE, я думаю, это будет хорошо.

Далее я ссылаюсь на Oracle Java-документы.

В лямбда-выражении вы должны заключать выражения в фигурные скобки ( {}). Однако вам не нужно заключать вызов метода void в фигурные скобки.
Например, следующее является допустимым лямбда-выражением:

email -> System.out.println(email)

И документ объясняет довольно четко. Надеюсь, что это может решить вашу проблему.

Ссылки: https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

Автор: Tipton Размещён: 05.11.2015 02:37

0 плюса

690 Репутация автора

Java лямбда-выражения улучшены с помощью основных правил,

  • Для одного аргумента скобки необязательны [например: a -> a a; (а) -> а б; ]
  • Для нуля или более одного аргумента скобки обязательны [например: () -> 10; а -> а * а; (а, б) -> а + б; ]
  • Для одной строки выражения фигурные скобки необязательны [например: a -> a a; a -> {return a a}; ]
  • или одна строка выражения ключевое слово return не является обязательным [например: a -> a a; a -> {return a a}; ]

Есть больше правил, которые вы можете соблюдать в Основы Лямбда-выражения в Java 8

Автор: Rupesh Agrawal Размещён: 27.05.2019 08:21
Вопросы из категории :
32x32