Java的Lambda表达式

Java的Lambda表达式

1. 什么是Lambda表达式

简单的说,Lambda表达式就是匿名方法。Lambda表达式让程序员能够使用更加简洁的代码,但是同样也使代码的可读性比较差。

Lambda表达式也叫做匿名方法或者闭包。

2. 和匿名内部类做对比

Lambda是匿名方法,这个时候我们会想想到匿名内部类,我们来回想一下匿名内部类的用法,比如下面的代码就是使用匿名内部类实现了一个线程。

public class Test {
  public static void main(String[] args) {
    Thread t = new Thread(new Runnable() {
      @Override
      public void run() {
        System.out.println("线程:" + Thread.currentThread().getName());
      }
    });
    t.start();
  }
}

我们一般的做法是写一个Runnable接口的实现类,然后new一个实现类再传给Thread的构造器。如下:

public class Test {

  public static void main(String[] args) {
    MyThread myThread = new MyThread();
    Thread t = new Thread(myThread);
    t.start();
  }

  static class MyThread implements Runnable {
    @Override
    public void run() {
      System.out.println("线程:" + Thread.currentThread().getName());
    }
  }

}

可以看到使用匿名内部类的话就省略了新建Runnable接口的实现类这一步骤。

3. 使用Lambda表达式

上面使用匿名内部类的写法,如果使用Lambda表达式可以写成下面这样:

public class Test {
  public static void main(String[] args) {
    Thread t = new Thread(() ->  {
      System.out.println("线程:" + Thread.currentThread().getName());
    });
    t.start();
  }
}

这样有一个问题,如果接口里面有多个方法,那么Lambda表达式怎么知道实现的是哪个方法呢?我们通过代码测试一下:

package com.wangjun.othersOfJava;

public class LambdaTest {

    public static void main(String[] args) {
        Animal a = () -> {  // 编译报错:The target type of this expression must be a functional interface
            System.out.println("狗狗吃饭");
        };
        a.eat();
    }
    interface Animal {
        public void eat();
        public void duty();
    }
}

可以看到编译报错,这个提到一个functional interface,就是函数式接口。函数式接口就是只有一个抽象方法的接口。这样,就不难理解了,原来Lambda表达式只支持函数式接口。

4. Lambda表达式使用的几种方式

package com.wangjun.othersOfJava;

public class LambdaTest {

    public static void main(String[] args) {

        // 带类型
        Animal a1 = (String str) -> {
            System.out.println("狗狗吃饭:" + str);
        };
        // 不带类型
        Animal a2 = (str) -> {
            System.out.println("狗狗吃饭:" + str);
        };
        // 不带括号
        Animal a3 = str -> {
            System.out.println("狗狗吃饭:" + str);
        };
        // 不带大括号
        Animal a4 = str -> System.out.println("狗狗吃饭:" + str);
        a1.eat("火腿肠");
        a2.eat("牛肉");
        a3.eat("面条");
        a4.eat("米饭");

        // 使用return返回
        Person p1 = () -> {
            return "老师的职责:教书育人!";
        };
        // 直接返回
        Person p2 = () -> "医生的职责:救死扶伤!";
        System.out.println(p1.duty());
        System.out.println(p2.duty());
    }

    // 没有返回值
    interface Animal {
        public void eat(String str);
    }
    // 有返回值
    interface Person {
        public String duty();
    }
}

4. Java的双冒号表达式

JDK8中有双冒号的用法,就是把方法当做参数传到stream内部,使stream的每个元素都传入到该方法里面执行一下。下面通过遍历一个List来说明一下双冒号和Lambda表达式使用方式的不同。

package com.wangjun.othersOfJava;

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class LambdaTest {

  public static void printStr(String str) {
    System.out.println(str);
  }

  public static void main(String[] args) {

    List<String> list = Arrays.asList("aaa","bbb","ccc");
    // 1.通常的遍历方式
    for(String str: list) {
      LambdaTest.printStr(str);
    }
    // 2.使用Lambda表达式遍历
    list.forEach(str -> {
      LambdaTest.printStr(str);
    });
    // 3.使用::遍历
    list.forEach(LambdaTest::printStr);
    // 下面的方法和上面等价,使用的是函数式编程
    Consumer<String> methodParam = LambdaTest::printStr; //方法参数
    list.forEach(x -> methodParam.accept(x));//方法执行accept
  }
}

原文地址:https://www.cnblogs.com/scuwangjun/p/9191226.html

时间: 2024-08-28 15:19:01

Java的Lambda表达式的相关文章

Java 8 lambda表达式示例

例1.用lambda表达式实现Runnable 我开始使用Java 8时,首先做的就是使用lambda表达式替换匿名类,而实现Runnable接口是匿名类的最好示例.看一下Java 8之前的runnable实现方法,需要4行代码,而使用lambda表达式只需要一行代码.我们在这里做了什么呢?那就是用() -> {}代码块替代了整个匿名类. 1 // Java 8之前: 2 new Thread(new Runnable() { 3 @Override 4 public void run() {

用Java 8 Lambda表达式实现设计模式:命令模式

链接:http://www.importnew.com/16789.html 在这篇博客里,我将说明如何在使用Java 8 Lambda表达式的函数式编程方式时实现命令设计模式.命令模式的目标是将请求封装成一个对象,从对客户端的不同类型请求,例如队列或日志请求参数化,并提供相应的操作.命令模式是一种通用编程方式,该方式基于运行时决策顺序来执行方法.模式的参与者如下: 命令 :声明用于执行操作的接口. 实体命令 :定义接收者对象和动作的绑定. 客户端 :创建实体命令实例并设置它的接收者. 调用者:

Java 8 Lambda表达式10个示例【存】

PS:不能完全参考文章的代码,请参考这个文件http://files.cnblogs.com/files/AIThink/Test01.zip 在Java 8之前,如果想将行为传入函数,仅有的选择就是匿名类,需要6行代码.而定义行为最重要的那行代码,却混在中间不够突出.Lambda表达式取代了匿名类,取消了模板,允许用函数式风格编写代码.这样有时可读性更好,表达更清晰.在Java生态系统中,函数式表达与对面向对象的全面支持是个激动人心的进步.将进一步促进并行第三方库的发展,充分利用多核CPU.尽

Java之Lambda表达式和Stream类简单例子

开心一笑 提出问题 java的lambda表达式和Stream如何使用??? 解决问题 Lambda表达式的语法 基本语法: (parameters) -> expression 或 (parameters) ->{ statements; } 看例子学习吧! 例一:定义一个AyPerson类,为之后的测试做准备. package com.evada.de; import java.util.Arrays; import java.util.List; class AyPerson{ priv

Java 8 lambda表达式20180404

Java 8 lambda表达式示例 我个人对Java 8发布非常激动,尤其是lambda表达式和流API.越来越多的了解它们,我能写出更干净的代码.虽然一开始并不是这样.第一次看到用lambda表达式写出来的Java代码时,我对这种神秘的语法感到非常失望,认为它们把Java搞得不可读,但我错了.花了一天时间做了一些lambda表达式和流API示例的练习后,我开心的看到了更清晰的Java代码.这有点像学习泛型,第一次见的时候我很讨厌它.我甚至继续使用老版Java 1.4来处理集合,直到有一天,朋

Java 8 Lambda表达式

Java 8中Lambda表达式就是一个函数接口,也就是只有一个抽象方法的接口. Java中,传递一个行为是通过传递一个代表某种行为的对象来实现,比如,需要给某个按钮注册一个事件监听: button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println("button clicked"); } }); 通过匿名内

[Java 8] Lambda表达式对递归的优化 - 使用尾递归

递归优化 很多算法都依赖于递归,典型的比如分治法(Divide-and-Conquer).但是普通的递归算法在处理规模较大的问题时,常常会出现StackOverflowError.处理这个问题,我们可以使用一种叫做尾调用(Tail-Call Optimization)的技术来对递归进行优化.同时,还可以通过暂存子问题的结果来避免对子问题的重复求解,这个优化方法叫做备忘录(Memoization). 本文首先对尾递归进行介绍,下一票文章中会对备忘录模式进行介绍. 使用尾调用优化 当递归算法应用于大

Java SE 8 for the Really Impatient读书笔记——Java 8 Lambda表达式

1. lambda表达式的语法 语法十分简单:参数->主体 1.1 参数 可以是零个参数,一个参数,也可以是多个参数,参数可以指定类型,在编译器可以推导出参数类型的情况下,也可以省略参数类型. 两个参数的例子: (String first, String second)-> Integer.compare(first.length(), second.length()) 0个参数的例子: () -> { for (int i = 0; i < 1000; i++) doWork()

JAVA 8 Lambda表达式-Lambda Expressions

Lambda表达式介绍 Lambda表达式是在java规范提案JSR 335中定义的,Java 8 中引入了Lambda表达式,并被认为是Java 8最大的新特性,Lambda表达式促进了函数式编程,简化了Java编程开发. 背景知识 匿名内部类 在Java中,匿名内部类一般适用于那些在Java应用中只会出现一次的实现类,举个例子,在标准的Swing或JavaFX应用中,有很多键盘和鼠标的事件处理程序,一般情况下,你不需要写一个单独的事件处理类,而是使用如下方式(有Swing编程经验的应该很熟悉