3.大家都学我也学。
@FunctionalInterface public interface Comparator<T> { int compare(T o1, T o2); boolean equals(Object obj); default Comparator<T> reversed() { return Collections.reverseOrder(this); } default Comparator<T> thenComparing(Comparator<? super T> other) { Objects.requireNonNull(other); return (Comparator<T> & Serializable) (c1, c2) -> { int res = compare(c1, c2); return (res != 0) ? res : other.compare(c1, c2); }; } ... }有小伙伴应该要说了,这个接口这么多方法,为什么还能是函数式接口?注意了啊,我们可以看到一个好像是抽象的 equals 方法,但是,因为 equals 是 Object 中的方法,这种对Object 类的方法的重新声明是会让方法变成一个具体的方法。所以,不要误会了,这里的抽象方法就只有 compare 方法。
public interface Runnable { public abstract void run(); } java.util.concurrent.Callable @FunctionalInterface public interface Callable<V> { V call() throws Exception; } java.lang.reflect.InvocationHandler @FunctionalInterface public interface InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable; }如何使用 Lambda 表达式?
public static <T> void sort(List<T> list, Comparator<? super T> c) { list.sort(c); }最开始的写法是这样的,由于 Comparator 是一个接口,不能直接实例化,所以需要一个类来实现这个接口作为真正的比较器类,然后将这个 Comparator 实例对象作为 sort 方法第二个参数传入,实现排序,如下:
public class KeyComparator implements Comparator<Integer> { @Override public int compare(Integer v1, Integer v2) { return v1 - v2; } } List<Integer> keys = Arrays.asList(9, 3, 5, 10, 2); Collections.sort(keys, new KeyComparator()); System.out.println(keys); // [2, 3, 5, 9, 10]后来,这种写法比较麻烦,于是用匿名内部类改写这种写法,我们不需要自己去编写一个类来实现这个接口了,直接用匿名内部类。就是这种写法:
List<Integer> keys = Arrays.asList(9, 3, 5, 10, 2); Collections.sort(keys, new Comparator<Integer>() { @Override public int compare(Integer v1, Integer v2) { return v1 - v2; } }); System.out.println(keys); // [2, 3, 5, 9, 10]现在,匿名内部类比起 Lambda 表达式,也是麻烦,我们用 Lambda 进行改写:
List<Integer> keys = Arrays.asList(9, 3, 5, 10, 2); Collections.sort(keys, (Integer v1, Integer v2) -> {return v1 - v2;}); System.out.println(keys); // [2, 3, 5, 9, 10]是吧,(Integer v1, Integer v2) -> {return v1 - v2;} 的写法,没有函数名,也能进行调用。
@FunctionalInterface public interface Runnable { public abstract void run(); } 未使用 Lambda(使用匿名内部类): new Thread(new Runnable() { @Override void run() { System.out.println("线程开始跑了"); } }).start();使用 Lambda:
// 写法一 new Thread(() -> { System.out.println("线程开始跑了") }).start(); // 写法二,一条语句,那么省略大括号、return 关键字及语句分号 new Thread(() -> System.out.println("线程开始跑了")).start();
@FunctionalInterface public interface Callable<V> { V call() throws Exception; } 未使用 Lambda(使用匿名内部类): FutureTask<String> stringFutureTask = new FutureTask<>(new Callable<String>() { @Override public String call() throws Exception { return "这里是返回值"; } }); stringFutureTask.run(); System.out.println(stringFutureTask.get());使用 Lambda:
// 一条语句,省略大括号、return 关键字及语句分号 FutureTask<String> stringFutureTask = new FutureTask<>(() -> "这里是返回值"); stringFutureTask.run(); System.out.println(stringFutureTask.get());情况三:方法一个参数、有返回值
@FunctionalInterface interface Recognizer { boolean recognize(int c); }未使用 Lambda(使用匿名内部类):
private final Recognizer A = new Recognizer() { @Override public boolean recognize(int c) { return c == 'a' || c == 'A'; } }使用 Lambda:
private final Recognizer A = (c) -> c == 'a' || c == 'A'; // 一个参数,可省略小括号 private final Recognizer A = c -> c == 'a' || c == 'A';情况四:方法多个参数、有返回值
List<Integer> keys = Arrays.asList(9, 3, 5, 10, 2); keys.sort(new Comparator()<Integer> { @Override public int compare(Integer v1, Integer v2) { return v1 - v2; } });使用 Lambda:
List<Integer> keys = Arrays.asList(9, 3, 5, 10, 2); // 多个参数以逗号分开,可省略类型,一条语句,省略大括号、return 关键字及语句分号 keys.sort((v1, v2) -> v1 - v2); System.out.println(keys);总结