【问题标题】:In Lambda Expressions (Java), how is an expression without parameter used?在 Lambda 表达式 (Java) 中,如何使用没有参数的表达式?
【发布时间】:2016-11-26 04:45:23
【问题描述】:

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

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

第三个似乎从未使用过。

您能否为这 3 个案例中的每一个都提供一个示例(案例 3 的一个额外示例会很好)来说明它们的用法?请让它们尽可能简单(最好以 list.stream().... 开头)

【问题讨论】:

  • 第三个好像没用过???我只是在这里使用它:stackoverflow.com/questions/40797960/chicken-egg-lifecycle
  • 供应商 sup = () -> 2;
  • 这些不是不同“种类”的 lambda 表达式(而且您甚至没有详尽地介绍这些选项)。第三种只是第一种的特例,其中只有零个参数。第二种是一种特殊的语法形式,如果只有一个参数并且您选择让编译器推断参数类型,您可以省略括号。您还可以选择让编译器推断所有参数类型,在这种情况下,您会得到类似(x,y,z) -> x+y+z 的信息。但它们都是相同的“种类”。

标签: java lambda java-8 java-stream


【解决方案1】:
  1. 第一个表达式将用于获取方法的 2 个参数并返回一个值。

  2. 第二个表达式将用于x -> x * x,您可以在其中获取方法的 1 个参数并返回一个值。

  3. 第三个表达式( ) -> x 将用于( ) -> x,您可以在其中为方法获取0 个参数并返回一个值。

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

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;

【讨论】:

    【解决方案2】:

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

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

    示例 1(通常是流式缩减),通过将到目前为止计算的总和和列表中的下一项传递给 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,如果元素在列表中为 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);
    

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

    【讨论】:

      【解决方案3】:

      在阅读下面的例子之前,首先要注意 Lambda 表达式可以写成任何 SAM(也称为函数式)接口(事实上,Lambda 表达式是一种语法糖 用于替换 Java 中冗长的匿名类(使用单一方法)。

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

      以下示例是利用现有的 JDK (1.8) 功能接口编写的,例如 CallableFunctionBiFunction(像这些,在 JDK 1.8 中有许多内置的功能接口,大多数时候,它们很容易满足我们的要求)。

      (1) (int x, int y) -> { 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 -> 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) () -> 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());
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-30
        相关资源
        最近更新 更多