有且只有一个抽象方法的接口。
@FunctionalInterface // 注解:检测接口是否是一个函数式接口
修饰符 interface 接口名称 {
public abstract void method(); // public abstract 还是推荐加上
}
函数式接口通常与Lambda表达式配合使用(戳这里:《【Java】lambda表达式与函数式接口的完美配合》)
下面给出几个常用的函数式接口:
Supplier—get——生产工厂
Consumer—accept——消费,即使用
Predicate—test——判断
Function—apply——类型转换
▍ Supplier——生产工厂
Supplier接口被称为生产型接口:指定泛型是什么类型,接口的get()方法就会生产什么样的类型的数据
具体生成一个怎样的数据?就由之后传入的Lambda表达式决定吧!
import java.util.function.Supplier;
public class Demo {
// 这里的语义是:生成一个字符串,生成怎样的字符串呢?这由Lambda表达式决定
private static String getString(Supplier<String> sup) {
return sup.get();
}
public static void main(String[] args) {
String s = getString(()->"Loli");
System.out.println(s);
}
}
// 练习:求数组元素最大值
public class Prac {
// 生成怎样的数字呢?这由Lambda表达式决定
private static Integer getMax(Supplier<Integer> sup){
return sup.get();
}
public static void main(String[] args) {
int[] arr = {2, 5, 12, 9};
int max = getMax(()->{
int maxNum = arr[0];
for(int n : arr){
maxNum = Math.max(maxNum, n);
}
return maxNum;
});
System.out.println("数组的最大值为" + max);
}
}
▍ Consumer——消费,即使用
与生产工厂Supplier相反,Consumer用来消费,即使用一个数据
具体怎样消费、怎样使用这个数据呢?就由之后传入的Lambda表达式决定吧!
import java.util.function.Consumer;
public class Demo01 {
public static void consume(String s, Consumer<String> con){
con.accept(s);
}
public static void main(String[] args) {
// 使用方式:打印
consume("Loli", (s)->{
System.out.println(s);
});
// 消费方式:反转后输出
consume("Loli", (s)->{
String s2 = new StringBuilder(s).reverse().toString();
System.out.println(s2);
});
}
}
/*
Consumer接口的andThen默认方法: 将两个Consumer组合在一起
*/
public class Demo02 {
public static void consume(String s, Consumer<String> con1, Consumer<String> con2) {
con1.andThen(con2).accept(s);
// 完全等价于
// con1.accept(s);
// con2.accept(s);
}
public static void main(String[] args) {
consume("loli", (s)->{
System.out.println(s.toUpperCase());
}, (s)->{
System.out.println(s.toLowerCase());
});
}
}
// 练习:格式化输出数组(按照【姓名】和【年龄】)
public class Prac {
public static void printer(Consumer<String> con1, Consumer<String> con2, String[] arr){
for(String s : arr){
con1.andThen(con2).accept(s);
}
}
public static void main(String[] args) {
String[] arr = {"Alice,12", "Chino,10", "Cocoa,9"};
printer((s)->{
System.out.println("姓名:" + s.split(",")[0] + ";");
}, (s)->{
System.out.println("年龄:" + s.split(",")[1] + ".\n");
}, arr);
}
}
▍ Predicate——判断
对某种数据类型的数据进行判断,返回一个布尔值
具体根据什么判断呢?就由之后传入的Lambda表达式决定吧!
import java.util.function.Predicate;
public class Demo01 {
public static boolean judge(String s, Predicate<String> pre){
return pre.test(s);
}
public static void main(String[] args) {
boolean bool = judge("loli", (s)-> s.length() > 5);
System.out.println(bool);
}
}
/*
三个方法————与、或、非
*/
public class Demo02 {
// 逻辑表达式
public static boolean judge1(String s, Predicate<String> pre1, Predicate<String> pre2) {
return pre1.and(pre2).test(s);
// 完全等价于return pre1.test(s) && pre2.test(s);
}
public static boolean judge2(String s, Predicate<String> pre1, Predicate<String> pre2){
return pre1.or(pre2).test(s);
// 完全等价于return pre1.test(s) || pre2.test(s);
}
public static boolean judge3(String s, Predicate<String> pre){
return pre.negate().test(s);
// return ! pre.test(s);
}
public static void main(String[] args) {
boolean bool1 = judge1("loli", (s) -> s.length() > 3, (s) -> s.contains("a"));
boolean bool2 = judge2("loli", (s) -> s.length() > 3, (s) -> s.contains("a"));
boolean bool3 = judge3("loli", (s) -> s.length() > 3);
}
}
// 练习:数组筛选功能(【名字】长度等于5,【年龄】大于等于10)
public class Prac {
public static String[] filter(String[] arr, Predicate<String> pre1, Predicate<String> pre2) {
List<String> list = new ArrayList<>();
for (String s : arr) {
if (pre1.and(pre2).test(s)) {
list.add(s);
}
}
return list.toArray(new String[list.size()]);
}
public static void main(String[] args) {
String[] arr = {"Alice,12", "Chino,10", "Cocoa,9"};
String[] res = filter(arr, (s) -> s.split(",")[0].length() == 5, (s) -> Integer.valueOf(s.split(",")[1]) >= 10);
System.out.println(Arrays.toString(res));
}
}
▍ Function——类型转换
对某种数据类型转化成另一种数据类型(甚至可以转化为原先的类型)
转换的过程是怎样的呢?就由之后传入的Lambda表达式决定吧!
import java.util.function.Function;
public class Demo {
public static int trans(String s, Function<String, Integer> fun){
return fun.apply(s);
}
public static void main(String[] args) {
int n = trans("233", (s)->Integer.parseInt(s));
System.out.println(n);
}
}
/*
同样拥有andThen方法
*/
public class Demo02 {
// 将字符串转化成整形后+10,再转化回字符串
public static String trans(String s, Function<String, Integer> fun1, Function<Integer, String> fun2) {
return fun1.andThen(fun2).apply(s);
}
public static void main(String[] args) {
String str = trans("12", (s) -> Integer.valueOf(s) + 10, (n) -> String.valueOf(n));
System.out.println(str);
}
}
// 练习————不练了不练了,和上面一样的套路
♪ End
♬ By a Lolicon