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

在Lambda表达式(Java)中,如何使用没有参数的表达式?,java,lambda,java-8,java-stream,Java,Lambda,Java 8,Java Stream,据我所知,有3种java lambda表达式 (int x,int y)->{return x+y;} x->x*x ()->x 第三个似乎从未使用过 你能给这三种情况中的每一种举例说明它们的用法吗?请尽量简单(最好从list.stream()开始)前两个示例与后一个不同。函数中的变量(lambda表达式)引用其参数 而在第三个示例中,x引用lambda表达式之外但词法范围内的变量(可以是来自方法的局部变量或实例变量) 示例1(通常为stream reduce)通过将到目前为止计算的总和和列表中

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

  • (int x,int y)->{return x+y;}
  • x->x*x
  • ()->x
  • 第三个似乎从未使用过


    你能给这三种情况中的每一种举例说明它们的用法吗?请尽量简单(最好从list.stream()开始)

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

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

    示例1(通常为stream reduce)通过将到目前为止计算的总和和列表中的下一项传递给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));
     }
    
    int x=我的默认值;
    //lambda引用上述变量以获取默认值
    map.computeFabSent(1,(整数键)->x);
    //当然,putIfAbsent()也可以实现同样的效果
    //但通常您会使用(整数键)->expensiveComputeOfValue(x)
    // ...
    //或者是执行者的常见例子
    公共未来computeAsync(最终整数值){
    //将同步计算结果的回调传递给Executor.submit()
    //回调引用了参数“value”
    返回executor.submit(()->computeSync(值));
    }
    
  • 第一个表达式将用于获取方法的2个参数并返回一个值

    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;
    
  • 第二个表达式将被使用
    x->x*x
    ,其中为方法获取1个参数并返回一个值

    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;
    
  • 第三个表达式
    ()->x
    将被使用
    ()->x
    ,其中您为方法获取0个参数并返回一个值

    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;
    
  • 我们买第三个吧。假设您有一个不接受参数并返回值的接口

    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;
    

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

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

    下面的示例是通过使用现有的JDK(1.8)功能接口编写的,如
    可调用的
    函数
    双函数
    (像这些,JDK 1.8中有许多内置功能接口,大多数时候它们很容易满足我们的要求

    (1)示例(intx,inty)->{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));
    
    (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());
    
    //在Lambda exp下面,输入参数为void,返回字符串
    Callable callabl=()->“我的Callable”;
    ExecutorService=Executors.newSingleThreadExecutor();
    Future=service.submit(可调用);
    System.out.println(future.get());
    
    第三个似乎从未使用过???我只是在这里使用它:suppliersup=()->2;这些并不是不同的lambda表达式的“种类”(您甚至还没有详细介绍这些选项)。第三个只是第一个的一个特例,其中只有零个参数。第二种是一种特殊的语法形式,如果只有一个参数并且您选择让编译器推断参数类型,则可以省略括号。您还可以选择让编译器推断所有参数类型,在这种情况下,您将得到类似
    (x,y,z)->x+y+z
    。但它们都是同一种东西。