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 来处理

    转自:https://www.cnblogs.com/zhenghengbin/p/9418961.html

  • 相关阅读:
    UVALive 7141 BombX
    CodeForces 722D Generating Sets
    CodeForces 722C Destroying Array
    CodeForces 721D Maxim and Array
    CodeForces 721C Journey
    CodeForces 415D Mashmokh and ACM
    CodeForces 718C Sasha and Array
    CodeForces 635C XOR Equation
    CodeForces 631D Messenger
    田忌赛马问题
  • 原文地址:https://www.cnblogs.com/panchanggui/p/10709092.html
Copyright © 2011-2022 走看看