1 package day14.lesson1;
2
3 /*
4 1 函数式接口
5
6 1.1 函数式接口概述
7
8 概念
9 有且仅有一个抽象方法的接口
10 java中的函数式编程体现就是Lambda表达式,所以函数式接口就是可以适用于Lambda使用的接口
11 只有确保接口中有且仅有一个抽象方法,java中的Lambda才能顺利进行推导
12 如何检测一个接口是不是函数式接口
13 @FunctionalInterface
14 放在接口定义的上方:如果接口是函数式接口,编译通过;如果不是,编译失败
15 注意事项
16 我们自己定义函数式接口的时候,@FunctionalInterface是可选的,就算我不写这个注解,只要保证满足函数
17 式接口定义的条件,也照样是函数式接口。但是,建议加上该注解
18 */
19 public class Demo1MyInter {
20 public static void main(String[] args) {
21 MyInter mi = () -> System.out.println("函数式接口"); // 根据局部变量的赋值得知Lambda对应的接口https://www.cnblogs.com/yppah/p/14874679.html
22 mi.show();
23 }
24 }
25
26 @FunctionalInterface
27 interface MyInter{
28 void show();
29
30 // void method(); //注解FunctionalInterface编译异常
31 }

1 package day14.lesson1;
2
3 /*
4 1.2 函数式接口作为方法的参数
5
6 需求描述
7 定义一个类(RunnableDemo),在类中提供两个方法
8 一个方法是:startThread(Runnable r) 方法参数Runnable是一个函数式接口
9 一个方法是主方法,在主方法中调用startThread方法
10 */
11 public class Demo2Runnable {
12 public static void main(String[] args) {
13 // 匿名内部类
14 startThread(new Runnable() {
15 @Override
16 public void run() {
17 System.out.println(Thread.currentThread().getName() + "线程启动了");
18 }
19 });
20
21 // Lambda表达式
22 startThread(() -> System.out.println(Thread.currentThread().getName() + "线程启动了"));
23 // 如果方法的参数是一个函数式接口,则可以使用Lambda表达式作为参数传递
24 }
25
26 private static void startThread(Runnable r){ // Runnable是函数式接口,可以作为形参
27 /*Thread t = new Thread(r);
28 t.start();*/
29 new Thread(r).start();
30 }
31
32 // Runnable源码
33 // @FunctionalInterface
34 // public interface Runnable {
35 // /**
36 // * When an object implementing interface <code>Runnable</code> is used
37 // * to create a thread, starting the thread causes the object's
38 // * <code>run</code> method to be called in that separately executing
39 // * thread.
40 // * <p>
41 // * The general contract of the method <code>run</code> is that it may
42 // * take any action whatsoever.
43 // *
44 // * @see java.lang.Thread#run()
45 // */
46 // public abstract void run();
47 // }
48 }

1 package day14.lesson1;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.Comparator;
6
7 /*
8 1.3 函数式接口作为方法的返回值
9
10 需求描述
11 定义一个类(ComparatorDemo),在类中提供两个方法
12 一个方法是:Comparator<String> getComparator() 方法返回值Comparator是一个函数式接口
13 一个方法是主方法,在主方法中调用getComparator方法
14 */
15 public class Demo3Comparator {
16 public static void main(String[] args) {
17 ArrayList<String> arrayList = new ArrayList<>();
18 arrayList.add("ccc");
19 arrayList.add("aa");
20 arrayList.add("e");
21 arrayList.add("dddd");
22 arrayList.add("bbbbb");
23 System.out.println("排序前:" + arrayList); // [ccc, aa, e, dddd, bbbbb]
24
25 // Collections.sort(arrayList); // [aa, bbbbb, ccc, dddd, e] 自然顺序(按字母顺序)排序
26
27 /*Collections.sort(arrayList, new Comparator<String>() {
28 @Override
29 public int compare(String s1, String s2) {
30 return s1.length() - s2.length();
31 }
32 }); // [e, aa, ccc, dddd, bbbbb] 按字符串长度排序*/
33
34 Collections.sort(arrayList, getComparator()); // 效果同上
35
36 System.out.println("排序后:" + arrayList);
37 }
38
39 private static Comparator<String> getComparator(){ // Comparator是函数式接口
40 //匿名内部类
41 /*Comparator<String> comparator = new Comparator<String>(){
42 @Override
43 public int compare(String s1, String s2) {
44 return s1.length() - s2.length();
45 }
46 };
47 return comparator;*/
48 // return new Comparator<String>() {
49 // @Override
50 // public int compare(String s1, String s2) {
51 // return s1.length() - s2.length();
52 // }
53 // };
54
55 // Lambda表达式
56 /*return (String s1, String s2) -> {
57 return s1.length() - s2.length();
58 };*/
59 return (s1, s2) -> s1.length()-s2.length();
60 // 如果方法的返回值是一个函数式接口,则可以使用Lambda表达式作为结果返回
61 }
62
63 // Comparator源码
64 // @FunctionalInterface
65 // public interface Comparator<T> {...}
66 }
