zoukankan      html  css  js  c++  java
  • Java的λ表达(lambda)

    λ表达的基本目的

        回调Java8的λ表达式 说明了Java8的λ表达式的基本用途:完毕了回调的原意——代码的參数化。

        回调:能够简单地说,假设你的方法须要override底层或JDK的某个类的方法,并且你从来没有自己调用过该方法,则该方法(有时候,也指被改写的方法)就是回调。比如

    • Applet定义的init()、start()、stop()和destroy();
    • 图形绘制方法paint(Graphics)、update(Graphics)和重载的repaint()。
    • java.lang.Runnable的run();
    • GUI中ActionListener的actionPerformed(ActionEvent e)...

         在Java8之前,回调的代码通常由匿名类提供,例如以下代码(完整代码见回调与Java8的λ表达式 )

            s.register(new IClient(){
                 @Override public void callback(int i){
                     System.out.println("==" + i + "0%");
                 }
            });
    如今则能够:
            IClient listener1=(i)->{System.out.println("+" + i + "0%");};
            s.register(listener1);
            s.register((i)->{System.out.println("++" + i + "0%");});
    显然,使用λ表达式提供回调代码较匿名类简洁,较Client implements IClient简洁得很多其它。

    λ表达式有三部分组成:(參数列表),箭头->,{一个代码块}

    由于IClient是仅有一个抽象方法的接口,既然唯一的抽象方法是

    public void callback(int i);

    那么,而编译器将赋值给IClient类型变量如listener1的“某λ表达式”,识别为给那个唯一的抽象方法提供方法体的匿名实现类的引用

    从代码输入的角度。λ表达式就能够尽可能的简单。

    • IClient listener1= (int i)->{System.out.println("+" + i + "0%");};  
       //IClient的唯一的抽象方法的方法名不须要了,肯定为
      callback提供方法体。也不能要方法名λ表达式的三部分,容不下方法名

    • listener1=(i)->{/**/};  
      //能够省略i的类型,编译器从唯一的抽象方法的形參列表中能够推导类型
    • listener1=i->{};
      //仅仅有单一的形參的时候,能够省略λ表达式的形參括号

    其它情况,你能够依照写程序最少的原则。自己试一试。

    比如

    1. (參数列表)部分:有多个參数时,能够(int i。int j)(i,j);一个參数,(i)、i->。无參数。()->
      如int getX()。其λ表达式为 ()->{return 0;} ()->0;
      //yqj2065还想省略形參括号,如同“->0”。敲打
    2. {一个代码块}部分:多个语句时,方法体;void方法,方法体;有返回值的单一语句。如int add(int i。int j)。λ表达式为(i,j)->{return i+j;} 或 (i,j)->i+j;

    函数接口

    为什么可以写出

    • IClient listener1=某λ表达式; 
    • s.register(某λ表达式);

    由于IClient是仅有一个抽象方法的接口——函数(型)接口(functional interface)

    1. IClient listener1=某λ表达式;
      编译器解读为 某λ表达式 为IClient的仅有抽象方法提供代码。

      尽管IClient“是一个”Object,能够
       Object obj= listener1;
      可是。
      Object obj= 某λ表达式;
      感觉上就不太靠谱,“某λ表达式”是为谁的仅有抽象方法提供代码呢?so。
      Object obj= (IClient)某λ表达式;//ok

    2. s.register(某λ表达式);
      由于依照register(IClient listener),编译器知道 某λ表达式 为IClient的仅有抽象方法提供代码。

        函数接口仅仅可以有一个抽象方法。

    如果IClient继承Runnable。又想作为函数接口@FunctionalInterface,就得给继承过来的run()提供方法体(这里给一个空方法体凑数)。

    package Lower;
    /**
     * @author yqj2065
     */
    @FunctionalInterface
    public interface IClient extends Runnable{
        int add(int i,int j);     
         @Override  default public  void run(){};
    }

    函数接口(一般地,普通接口)中使用 defaultkeyword,能够加入具有实现的方法,这个玩意就是Java接口的默认方法

    函数接口中出现默认方法,好像有点理由。一般接口中使用默认方法。參考纠结的默认方法



  • 相关阅读:
    python-装饰器
    Django-session相关操作+redis
    Could not connect to Redis at 127.0.0.1:6379: 由于目标计算机积极拒绝,无法连接。redis启动失败
    mybatis高级特性
    Elasticsearch从入门到熟练使用
    sharding-jdbc从入门到熟练使用
    mysql主从复制搭建(普通安装和docker方式)
    领域驱动设计入门及简单落地
    docker的一些基本命令
    docker发布jar包项目
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5033621.html
Copyright © 2011-2022 走看看