概述
- 函数式接口(Functional Interface)就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口。
- 函数式接口适用于函数式编程的场景,Java中的函数式百年城体现就是Lambda,所以函数式接口就是适用于Lambda使用的接口。Java中的Lambda可以被当中匿名内部类的语法糖
- 语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·约翰·兰达(Peter J. Landin)发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。通常来说使用语法糖能够增加程序的可读性,从而减少程序代码出错的机会。
格式
- 只要确保接口中有且仅有一个抽象方法即可
@FunctionalInterface // 这个注解检测这个接口是否式函数式接口 修饰符 interface 接口名称 { public abstract 返回值类型 方法名称(可选参数信息) // 其他非抽象方法 }
// 接口中的抽象方法的public abstract可省略 修饰符 interface 接口名称 { 返回值类型 方法名称(可选参数信息) // 其他非抽象方法 }
使用
-
函数式接口作为方法的参数
public static void main(String[] args) { show(new MyFunctionalInterface() { @Override public void method() { System.out.println("world"); } }); // Lambda表达式 show(()->{ System.out.println("nihao"); }); } public static void show(MyFunctionalInterface myInter){ myInter.method(); }
-
使用Lambda作为方法的参数和返回值
public static void startThread(Runnable run){ // 开启多线程 new Thread(run).start(); } public static void main(String[] args) { startThread(()->{ System.out.println("开启多线程:"+Thread.currentThread().getName()); }); }
public static Comparator<String> getComparator(){ /*return new Comparator<String>() { @Override public int compare(String s1, String s2) { return s2.length()-s1.length(); } };*/ /*return (String s1,String s2)->{ return s2.length()-s1.length(); };*/ return (s1,s2)->s2.length()-s1.length(); } public static void main(String[] args) { String[] sArr ={"aaa","b","cccda","da"}; getComparator(); Arrays.sort(sArr,getComparator()); System.out.println(Arrays.toString(sArr)); }
常用的函数式接口
- Supplier接口
-
public interface Supplier<T>
,接口仅包含一个无参的构造方法:T get()
。用来获取一个泛型参数指定类型的对象数据 -
被称为生产型接口
public static void main(String[] args) { String s= getString(() ->{ return "helloworld"; }); System.out.println(s); // helloworld } public static String getString(Supplier<String> sup){ return sup.get(); }
// 求数组元素的最大值 public static int getMax(Supplier<Integer> sup){ return sup.get(); } public static void main(String[] args) { int[] arrInt={100,12,56,430,160,32}; int result= getMax(()->{ int max=arrInt[0]; for (int val : arrInt) { if(val>max){ max=val; } } return max; }); System.out.println(result); }
- Consumer接口
-
public interface Consumer<T>
表示接受单个输入参数并且不返回结果的操作。 与大多数其他功能接口不同, Consumer预期通过副作用进行操作。 -
是一个消费型接口,泛型执行什么类型,就可以使用accpet方法消费什么类型的数据
-
方法:
void accept(T t)
对给定的参数执行此操作。public static void method(String name, Consumer<String> con){ con.accept(name); } public static void main(String[] args) { method("hello",(name)->{ System.out.println(name); // hello String reName=new StringBuilder(name).reverse().toString(); System.out.println(reName); // olleh }); }
-
default Consumer<T> andThen(Consumer<? super T> after)
返回一个组成的 Consumer ,依次执行此操作,然后执行 after操作。public static void method(String s, Consumer<String> con1,Consumer<String> con2){ con1.andThen(con2).accept(s); } public static void main(String[] args) { method("hello",(s)->{ System.out.println(s.toUpperCase()); // HELLO },(s)->{ System.out.println(s+"world"); // helloworld System.out.println(s.toLowerCase()); // hello }); }
public static void main(String[] args) { String[] arrStr={"迪丽热巴,18","古力娜扎,98","马尔扎哈,67"}; /* 打印结果: 姓名:迪丽热巴 年龄:18 姓名:古力娜扎 年龄:98 姓名:马尔扎哈 年龄:67 */ printInfo(arrStr,(s)->{ String name= s.split(",")[0]; System.out.print("姓名:"+name); },(s)->{ String age= s.split(",")[1]; System.out.println(" 年龄:"+age); }); } public static void printInfo(String[] arr, Consumer<String> con1,Consumer<String> con2){ for (String s : arr) { con1.andThen(con2).accept(s); } }
- Predicate接口
-
我们需要对某种类型的数据进行判断,从而得到一个Boolean值的结果。这时可以用
public interface Predicate<T>
接口1. 我们需要对某种类型的数据进行判断,从而得到一个Boolean值的结果。这时可以用public interface Predicate<T>
接口 -
抽象方法:
boolean test(T t)
,在给定的参数上评估这个谓词。public static boolean checkString(String s, Predicate<String> pre){ return pre.test(s); } public static void main(String[] args) { String str="abcde"; boolean b=checkString(str,(s)->{ return str.length()>4; }); System.out.println(b); }
-
默认方法:
3.1 anddefault Predicate<T> and(Predicate<? super T> other) 返回一个组合的谓词,表示该谓词与另一个谓词的短路逻辑AND。
public static boolean checkString(String s, Predicate<String> pre1,Predicate<String> pre2){ return pre1.and(pre2).test(s); } public static void main(String[] args) { boolean b=checkString("abcd",(s)->{ return s.length()>3; },(s)->{ // return s.indexOf("a") !=-1; return s.contains("a"); }); System.out.println(b); // true }
3.2 or
default Predicate<T> or(Predicate<? super T> other) 返回一个组合的谓词,表示该谓词与另一个谓词的短路逻辑或。
public static boolean checkString(String s, Predicate<String> pre1, Predicate<String> pre2){ return pre1.or(pre2).test(s); } public static void main(String[] args) { boolean b=checkString("abcd",(s)->{ return s.length()>6; },(s)->{ return s.contains("a"); // 是否包含a }); System.out.println(b); // true }
3.3 negate
default Predicate<T> negate() 返回表示此谓词的逻辑否定的谓词。
public static boolean checkString(String s, Predicate<String> pre){ return pre.negate().test(s); } public static void main(String[] args) { boolean b=checkString("abcd",(s)->{ return s.length()>3; }); System.out.println(b); // false }
3.4 例:集合信息筛选
public static void main(String[] args) { String[] arrStr={"迪丽热巴,女","古力娜扎,女","马尔扎哈,男","赵薇,女"}; ArrayList<String> list=filter(arrStr,(s)->{ return s.split(",")[0].length()==4; },(s)->{ return s.split(",")[1].equals("女"); }); System.out.println(list); // [迪丽热巴,女, 古力娜扎,女] } public static ArrayList<String> filter(String[] arr, Predicate<String> pre1,Predicate<String> pre2){ ArrayList<String> list=new ArrayList<>(); for (String s : arr) { boolean b=pre1.and(pre2).test(s); if(b){ list.add(s); } } return list; }
- Function接口
-
public interface Function<T,R>
,该接口用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件,后缀称为后置条件 -
抽象方法:
R apply(T t)
,将此函数应用于给定的参数。 根据T类型获取到类型R的结果public static void main(String[] args) { change("12",(s)->{ return Integer.parseInt(s); // 将字符串类型数字转换为Integer类型 }); } public static void change(String s, Function<String,Integer> fun){ Integer in=fun.apply(s); System.out.println(in); // 12 }
-
默认方法:
default <V> Function<T,V> andThen(Function<? super R,? extends V> after) 返回一个组合函数,首先将该函数应用于其输入,然后将 after函数应用于结果。
public static void main(String[] args) { change("123",(s)->{ Integer i=Integer.parseInt(s)+10; return i; },(i)->{ return i+""; }); } public static void change(String s, Function<String,Integer> fun1,Function<Integer,String> fun2){ String result=fun1.andThen(fun2).apply(s); System.out.println(result); }
-
练习
4.1 自定义函数模型拼接public static void main(String[] args) { String s="zhaosan,20"; int i=change(s,(s1)->{ return s1.split(",")[1]; },(s2)->{ return Integer.parseInt(s2); },(in)->{ return in+100; }); System.out.println(i); } public static int change(String s, Function<String,String> fun1, Function<String,Integer> fun2, Function<Integer,Integer> fun3){ return fun1.andThen(fun2).andThen(fun3).apply(s); }