美文网首页
(补·)Java Lambda表达(三)

(补·)Java Lambda表达(三)

作者: java部落 | 来源:发表于2017-11-15 16:22 被阅读0次

    Java 8 Lambda表达式要点

    10个Java lambda表达式、流API示例

    到目前为止我们看到了Java 8的10个lambda表达式,这对于新手来说是个合适的任务量,你可能需要亲自运行示例程序以便掌握。试着修改要求创建自己的例子,达到快速学习的目的。我还想建议大家使用Netbeans IDE来练习lambda表达式,它对Java 8支持良好。当把代码转换成函数式的时候,Netbeans会及时给你提示。只需跟着Netbeans的提示,就能很容易地把匿名类转换成lambda表达式。此外,如果你喜欢阅读,那么记得看一下Java 8的lambdas,实用函数式编程这本书,作者是Richard Warburton,或者也可以看看Manning的Java 8实战。不过,在你开始忙其它事情之前,先回顾一下Java 8的lambda表达式、默认方法和函数式接口的重点知识。

    1)lambda表达式仅能放入如下代码:预定义使用了 @Functional 注释的函数式接口,自带一个抽象函数的方法,或者SAM(Single Abstract Method 单个抽象方法)类型。这些称为lambda表达式的目标类型,可以用作返回类型,或lambda目标代码的参数。例如,若一个方法接收Runnable、Comparable或者 Callable 接口,都有单个抽象方法,可以传入lambda表达式。类似的,如果一个方法接受声明于 java.util.function 包内的接口,例如 Predicate、Function、Consumer 或 Supplier,那么可以向其传lambda表达式。

    2)lambda表达式内可以使用方法引用,仅当该方法不修改lambda表达式提供的参数。本例中的lambda表达式可以换为方法引用,因为这仅是一个参数相同的简单方法调用。

    list.forEach(n -> System.out.println(n)); 
    list.forEach(System.out::println);  // 使用方法引用
    

    然而,若对参数有任何修改,则不能使用方法引用,而需键入完整地lambda表达式,如下所示:

    list.forEach((String s) -> System.out.println("*" + s + "*"));
    

    事实上,可以省略这里的lambda参数的类型声明,编译器可以从列表的类属性推测出来。

    3)lambda内部可以使用静态、非静态和局部变量,这称为lambda内的变量捕获。

    4)Lambda表达式在Java中又称为闭包或匿名函数,所以如果有同事把它叫闭包的时候,不用惊讶。

    5)Lambda方法在编译器内部被翻译成私有方法,并派发 invokedynamic 字节码指令来进行调用。可以使用JDK中的 javap 工具来反编译class文件。使用 javap -p 或 javap -c -v 命令来看一看lambda表达式生成的字节码。大致应该长这样:

    private static java.lang.Object lambda$0(java.lang.String);
    

    6)lambda表达式有个限制,那就是只能引用 final 或 final 局部变量,这就是说不能在lambda内部修改定义在域外的变量。

    List<Integer> primes = Arrays.asList(new Integer[]{2, 3,5,7});
    int factor = 2;
    primes.forEach(element -> { factor++; });
    Compile time error : "local variables referenced from a lambda expression must be final or effectively final"
    

    另外,只是访问它而不作修改是可以的,如下所示:

    List<Integer> primes = Arrays.asList(new Integer[]{2, 3,5,7});
    int factor = 2;
    primes.forEach(element -> { System.out.println(factor*element); });
    

    输出:

    4
    6
    10
    14
    

    因此,它看起来更像不可变闭包,类似于Python。

    以上就是Java 8的lambda表达式的全部10个例子。此次修改将成为Java史上最大的一次,将深远影响未来Java开发者使用集合框架的方式。我想规模最相似的一次修改就是Java 5的发布了,它带来了很多优点,提升了代码质量,例如:泛型、枚举、自动装箱(Autoboxing)、静态导入、并发API和变量参数。上述特性使得Java代码更加清晰,我想lambda表达式也将进一步改进它。我在期待着开发并行第三方库,这可以使高性能应用变得更容易写。

    欢迎加入学习交流群569772982,大家一起学习交流。

    相关文章

      网友评论

          本文标题:(补·)Java Lambda表达(三)

          本文链接:https://www.haomeiwen.com/subject/jfhhvxtx.html