zoukankan      html  css  js  c++  java
  • java8新特性(二)_lambda表达式

    最近一直找java8相关新特性的文章,发现都太没有一个连贯性,毕竟大家写博客肯定都有自己的侧重点,这里找到一本书,专门介绍java8新特性的,感觉大家可以看看《写给大忙人看的JavaSE8》.这里我会结合书中的知识以及网上的知识,对于java8 的新特性进行总结,当然我自己写的也会有自己的侧重点。

    java8为什么增加了函数式编程

    java作为一门面向对象的编程语言诞生于20世纪90年代。在当时,面向对象编程是软件开发的主流模式。

    由于最近在并发和事件驱动(或者称为“互动”)编程中的优势,函数式编程又逐渐变得重要起来。

    这并不意味着面向对象编程不好,相反,最终的趋势是将面向对象编程和函数编程结合起来。

    java8主要在原来面向对象的基础上增加了函数式编程的能力.

    函数式编程的语言我就了解过一个_Erlang,有兴趣的大家可以看看Erlang这门语言。比如消息中间件rabbitmq 就是采用erlang写的。只要用过erlang的一定知道坚强2002和阿里的余锋。还有再推荐一个博客为“没有开花的树”的博主。至少对我帮助蛮多的。(有点扯远了)

    为什么要使用lambda表达式

    lambda表达式的定义

    lambda表达式是一段可以传递的代码,因此它可以被执行一次或者多次。

    实战代码对比

    之前我们要在另一个独立线程中执行一些逻辑时,通常会将代码放到一个实现Runnable接口的类的run方法中。如下面

    public class Worker implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 1000; i++) {
                System.out.println("doWork" + i);
            }
        }
    }
    
    
    

    执行代码

        public static void main(String[] args) {
            Worker worker = new Worker();
            new Thread(worker).start();
    
        }
    

    这段代码的关键在于,run方法中包含了你希望在另一个线程中需要执行的代码。

    到现在为止,在java 中向其他代码传递一段代码并不是很容易的。你不得不构建一个属于某个类的对象,由它的某个方法来包含所需的代码。

    我们看看使用lambda表达式重写上面的方法

            new Thread(() -> {
                for (int i = 0; i < 1000; i++) {
                    System.out.println("doWork" + i);
                }
            }).start();
    

    lambda表达式语法

    一般语法

    (Type1 param1,Type2 params,...) -> {
    
        statment1;
        statment2;
        .....
        return statmentM;
        
    }
    
    

    单参数语法

    可以省略前面的小括号,但是我一般都是带着

    param1 ->{
        ...
        ...
        return ...;
    }
    

    单语句语法

    可以省略后面的大括号

    param1 -> statment
    
    

    函数式接口

    在java中有许多已有的接口都需要封装代码块,如Runnable。lambda表达式与这些接口都是向后兼容的。

    对于只包含一个抽象方法的接口,你可以通过lambda表达式来创建该接口的对象。这种接口被称为函数式接口。

    这里注意一点,大家都知道接口中的方法是抽象的。事实上,接口经常会重新声明Object类中的方法。如toString等 这些方法命名并不是抽象的。

    我们看下Runnable的代码 源码

    @FunctionalInterface
    public interface Runnable {
        /**
         * When an object implementing interface <code>Runnable</code> is used
         * to create a thread, starting the thread causes the object's
         * <code>run</code> method to be called in that separately executing
         * thread.
         * <p>
         * The general contract of the method <code>run</code> is that it may
         * take any action whatsoever.
         *
         * @see     java.lang.Thread#run()
         */
        public abstract void run();
    }
    
    

    注意有个@FunctionalInterface 注解,有2个作用

    • 编译器会检查标注该注解的实体,检查它是否是只包含一个抽象方法的接口。
    • 在jacadoc页面也会包含一条声明,说明这个接口是一个函数式接口。

    但是这个注解并不是强制使用,从概念上讲,所有只含有一个抽象方法的接口都是函数式接口,但是使用@FunctionalInterface 注解会让你的代码更加清楚,毕竟代码的可读性是编程的第一规范。

    方法引用

    有时候,你想要传递给其他代码的操作已经有实现的方法。

    Class or instance :: method
    

    比如

    (x) ->  System.out.println(x);
    

    就等同于

     System.out::println;
    
    

    构造器引用

    • 构造器引用同方法引用类似,不同的是在构造器引用中方法名是 new.

    • 对于拥有多个构造器的类,选择使用哪个构造器取决于上下文

    Class :: new
    

    变量作用域

    外部变量在 lambda 表达式引用时,jdk 8 编译器会隐式做为 final 来处理

  • 相关阅读:
    第十一周学习总结
    个人冲刺——(六)
    第二阶段冲刺—第二天
    软件工程第十四周总结
    第二阶段冲刺—第一天
    大道至简阅读笔记02
    输入法用户体验评价
    软件工程第十三周总结
    人机交互-水王
    大道至简阅读笔记01
  • 原文地址:https://www.cnblogs.com/zhenghengbin/p/9418961.html
Copyright © 2011-2022 走看看