函数式接口
- 函数式接口:有且仅有一个抽象方法的接口
- 函数式接口适用于Lambda表达式
- 只有确保接口中有且仅有一个抽象方法,Lambda才能顺利推导
定义一个函数式接口
@FunctionalInterface //此注解表明是函数式接口
public interface MyInt {
void show();
}
测试类
public class MyInterDemo {
public static void main(String[] args) {
/*函数式接口可以 用作参数传递,用作局部变量*/
//1.用作局部变量
MyInt mi = ()->{
System.out.println("函数式接口用作局部变量");
};
mi.show();
}
}
运行结果
函数式接口用作局部变量
注意
- 满足函数式接口的情况下,@FunctionalInterface 可写可不写,建议写上
- 标注@FunctionalInterface的情况下,如果是函数式接口,编译通过;如果不是函数式接口,编译不通过
函数式接口作为方法的参数
需求:定义一个类RunnableDemo,在里面提供两个方法
一个方法是startThread(Runnable r),方法参数Runnable是一个函数式接口
在住方法中调用startThread方法
public class RunnableDemo {
public static void main(String[] args) {
//1.采用匿名内部类方式调用startThread方法
startThread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "线程启动了");
}
});
//2.采用Lambda表达式方式调用startThread方法
startThread(() -> System.out.println(Thread.currentThread().getName() + "线程启动了"));
}
/**
* 函数式接口作为方法的参数
*
* @param r 函数式接口
*/
private static void startThread(Runnable r) {
new Thread(r).start();
}
}
运行结果
Thread-1线程启动了
Thread-0线程启动了
注意
- 如果方法的参数是一个函数式接口,可以使用Lambda表达式作为参数传递
函数式接口作为方法的返回值
需求:定义一个类ComparatorDemo,在里面提供两个方法
一个方法是Comparator< String> getComparator, 方法返回值Comparator是一个函数式接口
在住方法中调用getComparator方法
public class ComparatorDemo {
public static void main(String[] args) {
//对字符串长度进行排序
//1.定义集合,存储字符串元素
List<String> list = new ArrayList<>();
list.add("hello");
list.add("word");
list.add("javase");
System.out.println("排序前:" + list);
//2.排序
//自然排序
Collections.sort(list);
System.out.println("自然排序后:" + list);
//比较器排序
Collections.sort(list,getCompara());
System.out.println("比较器排序后:" + list);
}
/**
* 比较器排序
*
* @return
*/
private static Comparator<String> getCompara() {
//Lambda表达式方式,字符串长度由小到大
return (s1, s2) -> s1.length() - s2.length();
}
}
运行结果
排序前:[hello, word, javase]
自然排序后:[hello, javase, word]
比较器排序后:[word, hello, javase]
注意
- 如果方法的返回值是一个函数式接口,可以使用Lambda表达式作为结果返回
常用函数式接口
Java8在Java.util.function包下提供了大量函数式接口
- Supplier
- Consumer
- Predicate
- Function
Supplier接口
Supplier < T >:包含一个无参的方法
- T get():获得结果
- 该方法不需要参数,他会按照某种实现逻辑(Lambda表达式)返回一个数据
- Supplier < T >被称为生产型接口,如果我们指定了接口的泛型,那么get()就会生产什么样的数据
案例1:
public class SupplierDemo {
public static void main(String[] args) {
//接受返回的String类型的数据
//String s = getString(() -> {
// return "世界杯";
//});
String s = getString(() -> "世界杯");
Integer i = getInt(() -> 13);
//输出数据
System.out.println(s);
System.out.println(i);
}
/**
* 返回接口泛型类型的数据
*
* @param str
* @return
*/
private static String getString(Supplier<String> str) {
return str.get();
}
private static Integer getInt(Supplier<Integer> in) {
return in.get();
}
}
运行结果:
世界杯
13
案例2:
需求:定义一个类SupplierTest,里面有一个int getMax(Supplier< Integer> sup)用于返回int数组中的最大值
public class SupplierTest {
public static void main(String[] args) {
//定义int数组
int[] arr = {5, 12, 65, 78, 22, 11};
//调用方法,并接收返回的数据
int maxValue = getMax(() -> {
int max = arr[0];
//比较大小
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max =