lambda表达式
只要是函数式接口(接口内只有一个未实现的方法,可以有其它默认方法),就可以用lambda表达式,也就是快速new一个匿名内部类。
实例化接口的三种方式
继承接口,并实现接口
直接实现匿名内部类
通过lambda表达式去实现匿名内部类
package org.khaoden.lambda; interface animal { void sound(); default void eat() { System.out.println("Eating"); }; } interface cat { void sound(); default void eat() { System.out.println("Eating1"); } } class Dog implements animal { public void sound() { System.out.println("Barking"); } } public class Lambda { public static void main(String[] args) { Dog d = new Dog(); d.sound(); System.out.println("~~~~~~~~~~~~~~~~~"); animal c = new animal() { @Override public void sound() { System.out.println("Meow"); } }; c.sound(); System.out.println("~~~~~~~~~~~~~~~~~"); animal a = () -> { System.out.println("Woof"); }; a.sound(); a.eat(); System.out.println("~~~~~~~~~~~~~~~~~"); } }
lambda表达式的匹配方式
- 如果没有参数类型,是通过函数的参数数量来匹配的,按照顺序匹配
- 如果有参数类型,就加上类型的匹配
例子
比较器的lambda写法
package org.khaoden.lambda; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; class Student { String name; Integer grade; public Student(String name, int grade) { this.name = name; this.grade = grade; } } public class example { public static void main(String[] args) { List<Student> list = new ArrayList<>(); list.add(new Student("khaoden", 10)); list.add(new Student("khaoden1", 9)); list.add(new Student("khaoden2", 8)); printListVal(list); // Collections.sort(list, new Comparator<Student>() { // @Override // public int compare(Student o1, Student o2) { // return o1.grade.compareTo(o2.grade); // } // }); // lambda表达式 // Collections.sort(list, (o1, o2) -> o1.grade.compareTo(o2.grade)); // 方法引用,必须是传入的值就是比较的,且一定是升序的 // Collections.sort(list, Integer::compareTo); // 每次拿一个值去比较,list的元素类型就是比较器方法的擦参数类型 // 对于有对应静态方法的可以直接使用 Collections.sort(list, Comparator.comparingInt(o -> o.grade)); printListVal(list); Runnable runnable = () -> System.out.println("hello world"); runnable.run(); Thread t = new Thread(() -> System.out.println("hello world from thread")); System.out.println("hello world1"); t.start(); } private static void printListVal(List<Student> list) { for (Student student : list) { System.out.println(student.name + " " + student.grade); } } }
使用注意
- lambda表达式本质就是对方法的快速实现,如果对应的类型有现成的方法,可以使用方法引用去调用。
- 方法引用不需要传递参数,直接把值传入比较即可。如果比较的是对应对象的属性,可以使用Comparator的静态方法,比如Integer是comparingInt(x -> x.val)
- lambda表达式的变量类型必须是接口,因为是用来匿名内部类的,写一个类完全没有意义,而且也没有接口继承类的。
Function
java提供了一系列的函数时接口
类型分别
消费者 accept
生产者 get
多功能函数 apply
普通函数
import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; public class Func { public static void main(String[] args) { // 消费者 Consumer<String> consumer = (t) -> { System.out.println(t); }; // 提供者 Supplier<String> supplier = () -> { return "hello world"; }; // 普通函数 Runnable runnable = () -> { System.out.println("hello world"); }; // 多功能函数 Function<String, String> function = (t) -> { return t; }; // 多参数功能函数 BiFunction<String, String, String> biFunction = (t, u) -> { return t + u; }; System.out.println(function.apply("hello world")); System.out.println(biFunction.apply("hello", " world")); System.out.println(supplier.get()); consumer.accept("hello world"); } }
常用接口
断言Predicate:返回值是boolean,根据传来的参数去判断
// 断言 Predicate<Integer> predicate = t -> t % 2 == 0; System.out.println(predicate.test(2)); // 正向判断 System.out.println(predicate.negate().test(2)); // 反向判断
实例
import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; public class FuncDEMO { public static void main(String[] args) { // 定义数字提供函数 Supplier<String> supplier = () -> "42"; // 定义偶数断言 Predicate<Integer> predicate = (t) -> t % 2 == 0; // 转换器,字符串转数字 Function<String, Integer> func = Integer::parseInt; // 消费者,打印数字 Consumer<Integer> consumer = System.out::println; Myfunc(predicate, func, supplier, consumer); Myfunc((t) -> t % 2 == 0, Integer::parseInt, () -> "43", System.out::println); } private static void Myfunc(Predicate<Integer> predicate, Function<String, Integer> func, Supplier<String> supplier, Consumer<Integer> consumer) { if (predicate.test(func.apply(supplier.get()))) { consumer.accept(func.apply(supplier.get())); } else { System.out.println("不是偶数"); } } }
- 简单示例,是函数式接口常用场景