标签:bar 特性 对象 引用 理解 数列 技术 函数重写 app
Lambda 本质是一个匿名函数,可以理解为一段可以传递的代码,像数据一样传输。
使用 Lambda 可以简化代码、使代码更紧凑、更灵活。
使用 Lambda 表达式前提 需要函数式接口支持。
注:
函数式接口:指的是 接口中只有一个抽象方法的接口。可以使用 @FunctionalInterface 注解去判断、检查是否为函数式接口。
@FunctionalInterface public interface Test { public void test(); // public void test2(); }
JDK 8 引入一个箭头操作符 “->”,或者叫 Lambda 操作符。
【格式:】 (参数列表) -> {Lambda 体}; 注: 参数列表指的是 方法的参数,即需要在 Lambda 体中执行的变量。 Lambda 体指的是 方法体,定义了需要执行的功能。 【语法:】 若出现一个参数的情况,可以将()省略。 若出现一行代码的情况,可以将{}省略。 对于多个参数的情况,可以省略参数类型(JVM 类型推断),但()不能省略。 若{}中只有一行代码,且为return语句,则可省略return 和 {}。
如下例,使用匿名函数 与 Lambda 的比较。
Lambda 可以省去很多代码,代码结构紧凑、简洁。
使用 Lambda 与使用 匿名函数类似, Lambda 体中即为 匿名函数重写的方法的方法体,参数列表为 匿名函数重写的方法的参数列表,使用时,直接调用方法名即可。
【举例:】 /** * 测试 Lambda 表达式用法 */ public class TestLambda { public static void main(String[] args) { String str = "helloworld"; // 使用 匿名函数 时 test(str, new TestLambdaFunction() { @Override public void test(String str) { System.out.println(str); } }); // 使用 Lambda 表达式,此方法等价于上面匿名函数的写法 // 只有一个参数,() 可省略,参数类型可省略(JVM自动进行类型推断), Lambda 体只有一行代码,{} 可省略。 test(str, x -> System.out.println(x)); } public static void test(String str, TestLambdaFunction testLambdaFunction) { testLambdaFunction.test(str); } } @FunctionalInterface interface TestLambdaFunction { void test(String str); }
使用 Lambda 表达式前提是为函数式接口,但是 每次都自定义函数式接口,很繁琐、蛋疼,所以 Java 8 内置了函数式接口,使用时套用即可。
【四大核心函数式接口:(其余函数式接口用法类似)】 Consumer<T> 消费型接口,有参数 T,没有返回值。 抽象方法: void accept(T t); Supplier<T> 供给型接口,没有参数,有返回值 T。 抽象方法: T get(); Function<T, R> 函数型接口,有参数 T,有返回值 R。 抽象方法:R apply(T var1); Predicate<T> 断言型接口,有参数 T,返回值为 boolean 型。 抽象方法: boolean test(T var1); 【举例:】 import java.util.Date; import java.util.function.Consumer; import java.util.function.Supplier; /** * 测试 Lambda 表达式用法 */ public class TestLambda { public static void main(String[] args) { String str = "helloworld"; // 测试 Consumer<T> 函数式接口,此处定义 Consumer<T> 函数式接口抽象方法的具体实现 testConsumer(str, x -> System.out.println(x)); // 测试 Supplier<T> 函数式接口,此处定义 Supplier<T> 函数式接口抽象方法的具体实现 testSupplier(() -> new Date()); } public static void testConsumer(String str, Consumer<String> consumer) { // 此处为 Consumer<T> 函数式接口抽象方法具体调用 consumer.accept(str); } public static void testSupplier(Supplier<Date> supplier) { // 此处为 Supplier<T> 函数式接口抽象方法具体调用 System.out.println(supplier.get()); } }
若 Lambda 体中的内容在其他方法中已经实现,可以通过 方法引用 去引用相关代码,从而减少代码的冗余。方法引用可以理解为 Lambda 的另一种表现形式。
【格式:】 对象名::实例方法名 类名::静态方法名 类名::实例方法名 注: 方法引用 的方法与函数式接口中的方法 返回值类型 以及 参数类型要一致。 当 Lambda 参数列表中 第一个参数 是实例方法的调用者,第二个参数是 实例方法的参数时,才可以使用 类::实例方法名。 比如:String::equals. 【举例:】 import java.io.PrintStream; import java.util.function.Consumer; /** * 测试 Lambda 表达式用法 */ public class TestLambda { public static void main(String[] args) { Consumer<String> consumer0 = new Consumer<String>() { @Override public void accept(String s) { System.out.println(s); } }; consumer0.accept("匿名函数"); // 一般 Lambda 表达式写法 Consumer<String> consumer1 = x -> System.out.println(x); consumer1.accept("hello"); PrintStream printStream = System.out; Consumer<String> consumer2 = x -> printStream.println(x); consumer2.accept("hello wrold"); // 使用 对象名::实例方法名 去改写 Lambda 表达式,本质与 Lambda 表达式一致 Consumer<String> consumer3 = printStream::println; consumer3.accept("world"); } }
与方法引用类似,此处是对构造器的引用,是 Lambda 针对构造器的一种写法。
【格式:】 类名::new 注: 构造器引用 的参数列表 与 函数式接口中方法的参数列表 要一致。 即通过方法参数去确认调用哪一个构造方法。 【举例:】 import java.util.function.Function; /** * 测试 Lambda 表达式用法 */ public class TestLambda { public static void main(String[] args) { // 普通 Lambda 表达式 Function<String, String> function = (x) -> new String(x).trim(); System.out.println(function.apply(" ddd hello ")); // Lambda 表达式 -- 构造器引用 Function<String, String> function1 = String::new; System.out.println(function1.apply(" hello ")); // 普通 Lambda 表达式,并创建一个对象实例,等价于 上面的构造器引用 Function<String, String> function2 = (x) -> new String(x); System.out.println(function2.apply(" hello ")); } }
与方法引用类似,此处是对数组引用,是 Lambda 针对数组的一种写法。
【格式:】 数组类型[]::new 【举例:】 import java.util.function.Function; /** * 测试 Lambda 表达式用法 */ public class TestLambda { public static void main(String[] args) { // 一般 Lambda 创建一个数组的写法 Function<Integer, String[]> function = x -> new String[x]; System.out.println(function.apply(10).length); // 使用数组引用创建一个 数组的写法 Function<Integer, String[]> function1 = String[]::new; System.out.println(function1.apply(20).length); } }
Stream API 是 JDK 8 中处理集合的抽象概念,可以对指定的集合进行复杂的操作,比如查找、过滤、映射数据等。
简单地理解:Stream API 提供了一种高效且易于使用的处理数据的方式。Stream 就是一个数据通道,一个数据 经过 该通道(一系列流水线操作)后得到一个新的数据。
Stream 不会存储数据、不会改变源对象(会创建一个新 Stream)、延迟操作。
Step1:创建流。
Step2:流水线操作(对流进行操作)。
Step3:终止流。
标签:bar 特性 对象 引用 理解 数列 技术 函数重写 app
原文地址:https://www.cnblogs.com/xiaoxi1314/p/12758125.html