标签: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