在Lambda Expressions(Java)中,如何使用没有参数的表达式?

NoM*_*ors 6 java lambda java-8 java-stream

据我所知,有3种java lambda表达式.

  1. (int x, int y) -> { return x + y; }
  2. x -> x * x
  3. ( ) -> x

第三个似乎从未使用过.

你能举一个例子来说明3个案例中的每个案例(案例3的另一个例子是好的)来说明它们的用法吗?请使它们尽可能简单(最好从list.stream()....开始)

Mri*_*jay 7

  1. 第一个表达式将用于获取方法的2个参数并返回值的位置.

  2. 第二个表达式将用于x -> x * x获取方法的1个参数并返回值的位置.

  3. 第三个表达式( ) -> x将用于( ) -> x获取方法的0参数并返回值的位置.

我们来看第三个.假设您有一个不带参数的接口并返回一个值.

static interface RandomMath {
    public int random();
}
Run Code Online (Sandbox Code Playgroud)

现在您想要实例化此接口及其实现.不使用lambda,将按如下方式完成: -

Random random = new Random();
RandomMath randomMath = new RandomMath() {
    @Override
    public int random() {
        return random.nextInt();
    }
};
Run Code Online (Sandbox Code Playgroud)

使用lambda就像: -

Random random = new Random();
RandomMath randomMath = () -> random.nextInt(); //the third type.
Run Code Online (Sandbox Code Playgroud)

类似地,对于前两个,它可以用于采用两个和一个参数并返回值的方法.

static interface PlusMath {
    public int plus(int a, int b);
}

PlusMath plusMath = (a, b) -> a + b;

static interface SquareMath {
    public int square(int a);
}

SquareMath squareMath = a -> a * a;
Run Code Online (Sandbox Code Playgroud)


Zby*_*000 5

前两个例子与上一个例子不同.函数中的变量(lambda表达式)指的是其参数.

而在第三个示例中,x引用lambda表达式之外但在词法范围内的变量(可以是方法或实例变量中的局部变量).

示例1(通常是stream reduce)通过将列表中到目前为止计算的sum和next项传递给lambda函数来计算总和:

 int sum = list.stream().reduce((int x, int y) -> x+y);
Run Code Online (Sandbox Code Playgroud)

例2,计算元素的方块:

 squares = list.stream().map((int x) -> x*x).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

示例3,如果元素在列表中为null,则将元素设置为默认值:

 final int x = MY_DEFAULT_VALUE;
 // lambda refers the the variable above to get the default
 defaults = list.stream().map((Integer v) -> v != null ? v : x);
Run Code Online (Sandbox Code Playgroud)

或者更好的例如3是地图原子方法:

 int x = MY_DEFAULT_VALUE;
 // lambda refers the the variable above to get the default
 map.computeIfAbsent(1, (Integer key) -> x);
 // the same could be achieved by putIfAbsent() of course
 // but typically you would use (Integer key) -> expensiveComputeOfValue(x)
 // ...
 // or quite common example with executor
 public Future<Integer> computeAsync(final int value) {
     // pass the callback which computes the result synchronously, to Executor.submit()
     // the callback refers to parameter "value"
     return executor.submit(() -> computeSync(value));
 }
Run Code Online (Sandbox Code Playgroud)