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

时间:2016-11-26 04:45:23

标签: java lambda java-8 java-stream

据我所知,有三种java lambda表达式。

  1. (int x, int y) -> { return x + y; }
  2. x -> x * x
  3. ( ) -> x
  4. 第三个似乎从未使用过。

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

3 个答案:

答案 0 :(得分:7)

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

  2.   
  3. 将使用第二个表达式x -> x * x,您可以获得方法的1个参数并返回值。

  4.   
  5. 第三个表达式( ) -> x将用于( ) -> x,其中您获得方法的0个参数并返回一个值。

  6.   

让我们采取第三个。假设您有一个不带参数的接口并返回一个值。

static interface RandomMath {
    public int random();
}

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

Random random = new Random();
RandomMath randomMath = new RandomMath() {
    @Override
    public int random() {
        return random.nextInt();
    }
};

使用lambda就像: -

Random random = new Random();
RandomMath randomMath = () -> random.nextInt(); //the third type.

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

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;

答案 1 :(得分:5)

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

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

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

 int sum = list.stream().reduce((int x, int y) -> x+y);

示例2,计算元素的正方形:

 squares = list.stream().map((int x) -> x*x).collect(Collectors.toList());

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

 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);

或者更好,例如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));
 }

答案 2 :(得分:3)

在完成以下示例之前,请注意,可以为任何SAM(也称为Functional)接口编写Lambda表达式(事实上, Lambda表达式是一种语法糖用于替换Java中的详细匿名类(使用单个方法)。

单个抽象方法接口或功能接口是一个只包含一个abstract方法的接口),您可以查看here。如果您知道这一点,您可以编写(使用)任意数量的自己的Functional接口,然后根据每个Functional接口方法编写不同的Lambda表达式。

下面的示例是通过使用现有的JDK(1.8)功能接口编写的,如CallableFunctionBiFunction(就像这些,有很多内置的JDK 1.8中的功能接口,大多数时候它们都很符合我们的要求)。

(1)(int x,int y) - &gt;的示例{return x + y; }

//Below Lamda exp, takes 2 Input int Arguments and returns string
BiFunction<Integer, Integer, String> biFunction = (num1, num2) -> 
               "Sum Is:" +(num1 + num2);
System.out.println(biFunction.apply(100, 200));

(2)x - &gt;的示例x * x

//Below Lamda exp, takes string Input Argument and returns string
list.stream().map((String str1) -> 
       str1.substring(0, 1)). 
           forEach(System.out::println);    

(3)() - &gt;的示例x

//Below Lambda exp, Input argument is void, returns String
Callable<String> callabl = () -> "My Callable";
ExecutorService service =  Executors.newSingleThreadExecutor();
Future<String> future = service.submit(callable);
System.out.println(future.get());