【Java】Java8-Lambda

Java8-Lambda

林的幸福发布于 今天 02:31

简介

Lambda 表达式是 Java 1.8 跟 Stream 机制一同推出的。Lambda 表达式极大地减少了代码量,增加了代码的可读性。
引入 Lambda 表达式之后,Java 开始支持把函数作为参数传递。

前置条件

使用 Lambda 表达式的前置条件,作为参数的接口必须是函数式接口

  1. 首先类型必须是接口 interface,不能是类 class。比如,抽象类就不可以。
  2. 函数式接口有且仅有一个未被覆写的抽象方法

举例:

  • Object 中方法不算

// MyRunnable 仍然算是一个“函数式接口”

public interface MyRunnable extends Runnable {

String toString();

boolean equals(Object obj);

int hashCode();

}

  • 接口中的 default 方法不算

// MyRunnable2 仍然算是一个“函数式接口”

public interface MyRunnable2 extends Runnable {

default void run2() {}

}

FunctionalInterface 注解

@FunctionalInterface 可以帮助我们在编译期识别出一个接口是否是“函数式接口”:

【Java】Java8-Lambda

参数的传递

假如我们有一个如下含义的“函数式接口”:

@FunctionalInterface

public interface Formatter {

void format(String name, int age);

}

我们可以构造一个测试:

public class LambdaTest {

public static void main(String[] args) {

print((String name, int age)-> System.out.println(String.format("name:%s age:%d", name, age)), "ziyu", 18);

}

public static void print(Formatter formatter, String name, int age) {

formatter.format(name, age);

}

}

多个参数

当有多个参数时,可以选择省略所有参数类型声明:
【Java】Java8-Lambda
注意:
不能省略一部分保留一部分。(String name, age) -> System.out.println(name); 这是不合法的!

单个参数

【Java】Java8-Lambda
当只有一个参数时,除了可以省略参数类型,还可以进一步省略掉括号。

编写方式

没有返回值

Runnable 就是一个常用的“函数式接口”,它的抽象方法 run() “没有返回值”, 刚好适合用于此处的演示。测试例子如下:

public class LambdaTest2 {

public static void main(String[] args) {

runIt(()->{

System.out.println("123");

});

}

static void runIt(Runnable runnable) {

new Thread(runnable).start();

}

}

【Java】Java8-Lambda

  • 如果写成多行表达式,那么需要 {} 来表示代码块,且每一行代码结束时需要书写 ; 表示语句的结束。
  • 如果代码块中只有一条语句,那么可以通过省略 {}; 来简写为单行表达式

有返回值

我们定义一个 IdFactory 接口来做演示:

public interface IdFactory {

String generateId();

}

我们的示例代码如下:

import java.util.UUID;

public class LambdaTest3 {

public static void main(String[] args) {

String name = getId(()-> UUID.randomUUID() + "");

System.out.println(name);

}

static String getId(IdFactory factory) {

return factory.generateId();

}

}

【Java】Java8-Lambda

  • 如果写成多行表达式,除了需要 {} 来表示代码块,和每一行代码结束时需要书写 ; 表示语句的结束以外,还应该在需要返回值的方法用 return 来返回值。
  • 如果代码块中只有一条语句,那么可以通过省略 {}; 以及 return 来简写为单行表达式

方法引用

比如我们要写一段代码,用来打印出完整的加法表达式 a + b = c,并且要求根据 a 和 b 求出 c 作为函数返回值。
首先我们定一个“计算器”接口:

public interface Calculator {

int compute(int a, int b);

}

接着我们写一个测试用例:

public class LambdaTest3 {

public static void main(String[] args) {

int a = 10;

int b = 20;

// 这里不能用 (a, b), 那样的话会产生歧义,使得编译器报错

runIt((x, y)->{

System.out.print(x);

System.out.print(" + ");

System.out.print(y);

System.out.print(" = ");

System.out.println(x + y);

return x + y;

}, a, b);

}

static void runIt(Calculator calculator, int a, int b) {

calculator.compute(a, b);

}

}

静态方法引用

【Java】Java8-Lambda

  • 在 LambdaTest2 中定一个静态方法 sum

  • 使用静态方法引用 LambdaTest2::sum

  • 这样在运行静态方法 runIt 中的第一行 calculator.compute(a, b) 时,ab 会通过静态方法引用传递给静态方法 sum

通过这种方式,即简化了参数的传递,也把“多行表达式”简化为了“单行表达式”

成员方法引用

【Java】Java8-Lambda

  • new LambdaTest2()::sum: 先新建对象 LambdaTest2,并且通过该对象来使用成员变量引用
    小贴士:
    如果先声明变量 obj,再使用 obj::sum 也是合法的。

public static void main(String[] args) {

int a = 10;

int b = 20;

LambdaTest2 obj = new LambdaTest2();

runIt(obj::sum, a, b);

}

总结

  • Lambda表达式的前置条件:必须是“函数式接口”
  • 单个参数传递时,可以省略参数两端的括号。参数的类型可以一起省略。
  • 编写的方式主要包括单行表达式和多行表达式
  • 可以使用方法引用来把多行表达式写成单行表达式。方法引用又包括了静态方法引用和动态方法引用。

java

本文系转载,阅读原文

https://www.cnblogs.com/kendoziyu/p/java8-lambda-expression.html

阅读 18发布于 今天 02:31

avatar

林的幸福

0 声望

0 粉丝

0 条评论

得票时间

avatar

林的幸福

0 声望

0 粉丝

宣传栏

简介

Lambda 表达式是 Java 1.8 跟 Stream 机制一同推出的。Lambda 表达式极大地减少了代码量,增加了代码的可读性。
引入 Lambda 表达式之后,Java 开始支持把函数作为参数传递。

前置条件

使用 Lambda 表达式的前置条件,作为参数的接口必须是函数式接口

  1. 首先类型必须是接口 interface,不能是类 class。比如,抽象类就不可以。
  2. 函数式接口有且仅有一个未被覆写的抽象方法

举例:

  • Object 中方法不算

// MyRunnable 仍然算是一个“函数式接口”

public interface MyRunnable extends Runnable {

String toString();

boolean equals(Object obj);

int hashCode();

}

  • 接口中的 default 方法不算

// MyRunnable2 仍然算是一个“函数式接口”

public interface MyRunnable2 extends Runnable {

default void run2() {}

}

FunctionalInterface 注解

@FunctionalInterface 可以帮助我们在编译期识别出一个接口是否是“函数式接口”:

【Java】Java8-Lambda

参数的传递

假如我们有一个如下含义的“函数式接口”:

@FunctionalInterface

public interface Formatter {

void format(String name, int age);

}

我们可以构造一个测试:

public class LambdaTest {

public static void main(String[] args) {

print((String name, int age)-> System.out.println(String.format("name:%s age:%d", name, age)), "ziyu", 18);

}

public static void print(Formatter formatter, String name, int age) {

formatter.format(name, age);

}

}

多个参数

当有多个参数时,可以选择省略所有参数类型声明:
【Java】Java8-Lambda
注意:
不能省略一部分保留一部分。(String name, age) -> System.out.println(name); 这是不合法的!

单个参数

【Java】Java8-Lambda
当只有一个参数时,除了可以省略参数类型,还可以进一步省略掉括号。

编写方式

没有返回值

Runnable 就是一个常用的“函数式接口”,它的抽象方法 run() “没有返回值”, 刚好适合用于此处的演示。测试例子如下:

public class LambdaTest2 {

public static void main(String[] args) {

runIt(()->{

System.out.println("123");

});

}

static void runIt(Runnable runnable) {

new Thread(runnable).start();

}

}

【Java】Java8-Lambda

  • 如果写成多行表达式,那么需要 {} 来表示代码块,且每一行代码结束时需要书写 ; 表示语句的结束。
  • 如果代码块中只有一条语句,那么可以通过省略 {}; 来简写为单行表达式

有返回值

我们定义一个 IdFactory 接口来做演示:

public interface IdFactory {

String generateId();

}

我们的示例代码如下:

import java.util.UUID;

public class LambdaTest3 {

public static void main(String[] args) {

String name = getId(()-> UUID.randomUUID() + "");

System.out.println(name);

}

static String getId(IdFactory factory) {

return factory.generateId();

}

}

【Java】Java8-Lambda

  • 如果写成多行表达式,除了需要 {} 来表示代码块,和每一行代码结束时需要书写 ; 表示语句的结束以外,还应该在需要返回值的方法用 return 来返回值。
  • 如果代码块中只有一条语句,那么可以通过省略 {}; 以及 return 来简写为单行表达式

方法引用

比如我们要写一段代码,用来打印出完整的加法表达式 a + b = c,并且要求根据 a 和 b 求出 c 作为函数返回值。
首先我们定一个“计算器”接口:

public interface Calculator {

int compute(int a, int b);

}

接着我们写一个测试用例:

public class LambdaTest3 {

public static void main(String[] args) {

int a = 10;

int b = 20;

// 这里不能用 (a, b), 那样的话会产生歧义,使得编译器报错

runIt((x, y)->{

System.out.print(x);

System.out.print(" + ");

System.out.print(y);

System.out.print(" = ");

System.out.println(x + y);

return x + y;

}, a, b);

}

static void runIt(Calculator calculator, int a, int b) {

calculator.compute(a, b);

}

}

静态方法引用

【Java】Java8-Lambda

  • 在 LambdaTest2 中定一个静态方法 sum

  • 使用静态方法引用 LambdaTest2::sum

  • 这样在运行静态方法 runIt 中的第一行 calculator.compute(a, b) 时,ab 会通过静态方法引用传递给静态方法 sum

通过这种方式,即简化了参数的传递,也把“多行表达式”简化为了“单行表达式”

成员方法引用

【Java】Java8-Lambda

  • new LambdaTest2()::sum: 先新建对象 LambdaTest2,并且通过该对象来使用成员变量引用
    小贴士:
    如果先声明变量 obj,再使用 obj::sum 也是合法的。

public static void main(String[] args) {

int a = 10;

int b = 20;

LambdaTest2 obj = new LambdaTest2();

runIt(obj::sum, a, b);

}

总结

  • Lambda表达式的前置条件:必须是“函数式接口”
  • 单个参数传递时,可以省略参数两端的括号。参数的类型可以一起省略。
  • 编写的方式主要包括单行表达式和多行表达式
  • 可以使用方法引用来把多行表达式写成单行表达式。方法引用又包括了静态方法引用和动态方法引用。

以上是 【Java】Java8-Lambda 的全部内容, 来源链接: utcz.com/a/108824.html

回到顶部