Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码 像数据一样进行传递)。可以写出更简洁、更 灵活的代码。作为一种更紧凑的代码风格,使 Java的语言表达能力得到了提升.
/** * 未使用 lambda 表达式 */ @Test public void test01() { Comparator<Integer> comparator1 = new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { return Integer.compare(o1,o2); } }; TreeSet set = new TreeSet(comparator1); } /** * 使用 lambda 表达式 */ @Test public void test02() { // 使用 lambda Comparator<Integer> comparator = (o1,o2) -> Integer.compare(o1,o2); TreeSet set = new TreeSet(comparator); }
Lambda 表达式在Java 语言中引入了一个新的语法元 素和操作符。这个操作符为 “->” , 该操作符被称 为 Lambda 操作符或剪头操作符。它将 Lambda 分为 两个部分:
左侧:指定了 Lambda 表达式需要的所有参数
右侧:指定了 Lambda 体,即 Lambda 表达式要执行 的功能。
// 语法格式一: 无参, 无返回值, lambda 体只需要执行一条语句 Runnable runnable = () -> System.out.println("hello world"); // 语法格式二: 有一个参数, 并且无返回值 Consumer<String> consumer = (args) -> System.out.println(args); // 语法格式三: 只有一个参数时,参数的小括号可以省略 Consumer<String> consumer2 = args -> System.out.println(args); // 语法格式四: lambda 需要两个参数,多行执行语句,并且有返回值 Comparator<Integer> comparator = (a, b) -> { System.out.println("hello world"); return Integer.compare(a, b); }; // 语法格式五: lambda 需要两个参数,一条执行语句,并且有返回值 Comparator<Integer> comparator2 = (a, b) -> Integer.compare(a, b); // 语法格式六: lambda 表达式的参数列表的数据类型可以省略不写,因为 jvm 编译器可以通过上下文推断出数据类型,即"类型推断" Comparator<Integer> comparator3 = (Integer a, Integer b) -> Integer.compare(a, b);
一个抽象方法不会报错.
两个抽象方法编译报错.
消费型函数接口
源码:
@FunctionalInterface public interface Consumer<T> { void accept(T t); }
Demo:
供给型函数接口
源码:
@FunctionalInterface public interface Supplier<T> { T get(); }
Demo:
函数型函数接口
源码:
@FunctionalInterface public interface Function<T, R> { R apply(T t); }
Demo:
断言型函数接口
源码:
@FunctionalInterface public interface Predicate<T> { boolean test(T t); }
Demo:
学会了内置四大核心函数式接口,在学习其他的就比较简单了.具体的可以自己查看源码,看看接口中的唯一方法是什么.
部分:
全部:
当要传递给 Lambda 体的操作,已经有实现的方法了,可以使用方法引用! (实现抽象方法的参数列表,必须与方法引用方法的参数列表保持一致!) 方法引用:使用操作符 “::” 将方法名和对象或类的名字分隔开来。 如下三种主要使用情况:
类为:
Integer
静态方法名:compare
简单示例:
源码:
/** * 类::静态方法名 */ @Test public void test09() { // 例如:创建比较器 Comparator<Integer> comparator1 = (o1, o2) -> Integer.compare(o1, o2); // 等同于 Comparator<Integer> comparator2 = Integer::compare; System.out.println(comparator1.compare(1, 2)); System.out.println(comparator2.compare(1, 2)); }
对象:
PrintStream
静态方法名:println
简单示例:
源码:
/** * 对象::实例方法名 */ @Test public void test13() { // 例如:这个函数是打印传入的 name 值 Consumer<String> consumer1 = (name) -> System.out.println(name); // 创建对象 PrintStream ps = System.out; // 等同于 Consumer<String> consumer2 = ps::println; consumer1.accept("zcsh1"); consumer1.accept("zcsh2"); }
类:
String
实例方法名:equals
简单实例:
格式:
ClassName::new
与函数式接口相结合,自动与函数式接口中方法兼容。 可以把构造器引用赋值给定义的方法,与构造器参数 列表要与接口中抽象方法的参数列表一致!
简单示例:
源码:
private class Employee { private String name = "zcsh"; } /** * 无参构造器引用 */ @Test public void test12() { // 例如创建一个初始的 employee 对象 Supplier<Employee> supplier1 = () -> new Employee(); // 等同于 Supplier<Employee> supplier2 = Employee::new; System.out.println(supplier1.get().name); System.out.println(supplier2.get().name); }
简单示例:
源码:
private class Employee2 { private String name = "zcsh"; public Employee2(String name) { this.name = name; } } /** * 有参构造器引用 */ @Test public void test13() { // 例如创建一个初始的 employee 对象 Function<String, Employee2> function1 = (name) -> new Employee2(name); // 等同于 Function<String, Employee2> function2 = Employee2::new; System.out.println(function1.apply("zcsh1").name); System.out.println(function2.apply("zcsh2").name); }
简单示例:
源码:
/** * 数组引用 */ @Test public void test14() { // 创建一个长度为 length 的数组 Function<Integer,Integer[]> function1 = (length) -> new Integer[length]; // 等同于 Function<Integer,Integer[]> function2 = Integer[]::new; System.out.println(function1.apply(10).length); System.out.println(function2.apply(10).length); }