函数式接口概述
- 函数式接口:有且仅有一个抽象方法的接口
java中的函数式编程体现的就是Lambda表达式,所以函数式接口就是可以适用于Lambda使用的接口;只有确保接口中有且仅有一个抽象方法,java中的Lambda才能顺利地进行推导 - 如何检测一个接口是不是函数式接口呢?
①@FunctionalInterface
②放在接口定义的上方:如果接口是函数式接口,编译通过;如果不是,编译失败。 - 注意
我们自己在定义函数式接口的时候。@FunctionalInterface是可选的。就算我不写这个注解,只要保证满足函数式接口定义的条件,也照样是接口。但是,建议加上该注解
函数式接口作为方法的参数
如果方法的参数是一个函数式接口,我们可以使用Lambda表达式作为参数传递
public class RunnableDemo {
public static void main(String[] args) {
//匿名函数内部类
startThread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"线程启动了!");
}
});
//Lambda
startThread(()-> System.out.println(Thread.currentThread().getName()+"线程启动了!"));
}
private static void startThread(Runnable runnable){
Thread thread = new Thread(runnable);
thread.start();
}
}
函数式接口作为方法的返回值
如果方法的返回值是一个函数式接口,我们可以使用Lambda表达式作为结果返回
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class ComparatorDemo {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("aaaaa");
arrayList.add("ddd");
arrayList.add("cccc");
arrayList.add("bb");
System.out.println("排序前" + arrayList);
Collections.sort(arrayList, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
String s1 = (String) o1;
String s2 = (String) o2;
return s2.length() - s1.length();
}
});
System.out.println("排序后" + arrayList);
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class ComparatorDemo {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("aaaaa");
arrayList.add("ddd");
arrayList.add("cccc");
arrayList.add("bb");
System.out.println("排序前"+arrayList);
Collections.sort(arrayList, getComparator());
System.out.println("排序后"+arrayList);
}
private static Comparator<String> getComparator() {
//匿名内部类
Comparator<String> comparator = new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.length() - o2.length();
}
};
return comparator;
}
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class ComparatorDemo {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("aaaaa");
arrayList.add("ddd");
arrayList.add("cccc");
arrayList.add("bb");
System.out.println("排序前"+arrayList);
Collections.sort(arrayList, getComparator());
System.out.println("排序后"+arrayList);
}
private static Comparator<String> getComparator() {
//匿名内部类
return (String s1,String s2)->s1.length()-s2.length();
}
}
常用的函数式接口
- Supplier接口
Supplier<T>:包含一个无参的方法
①T get():获得结果
②该方法不需要参数,它会按照某种实现逻辑(由Lambda表达式)返回一个数据
③Supplier<T>接口也被称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中的get方法就会生产什么类型的数据供我们使用。
public class supplier {
public static void main(String[] args) {
String s = getString(()->"hello world");
System.out.println(s);
Integer i = getInteger(()->11);
System.out.println(i);
}
private static String getString(Supplier<String> sp){
return sp.get();
}
private static Integer getInteger(Supplier<Integer> sp){
return sp.get();
}
}
- Consumer接口
Consumer接口:包含两个方法
①void accept(T t):对给定的参数进行操作
②default Consumer<T> andThen(Consumer after):返回一个组合的Consumer,依次执行此操作,然后执行after操作
③Consumer<T>接口也被称为消费者接口,它消费的数据的数据类型由泛型决定
public class ConsumerDemo {
public static void main(String[] args) {
operatorString("小糊涂",(String s)-> System.out.println(new StringBuilder(s).reverse().toString()));
operatorString("智障猿",(String s)-> System.out.println(new StringBuilder(s).reverse().toString()),(String s)-> System.out.println(s));
}
//定义一个方法,消费一个字符串数据
private static void operatorString(String name, Consumer<String> con){
con.accept(name);
}
//定义一个方法用不同的方式消费同一个字符串数据
private static void operatorString(String name,Consumer<String> con1,Consumer<String> con2){
// con1.accept(name);
// con2.accept(name);
con1.andThen(con2).accept(name);
}
}
public class ConsumerDemo2 {
public static void main(String[] args) {
String[] strArray = {"林青霞,30", "张曼玉,20", "王祖贤,50"};
printInfo(strArray, (String s) -> {
String name = s.split(",")[0];
System.out.println("姓名为"+name);
}
, (String s) -> {
String age = s.split(",")[1];
System.out.println("年龄为"+age);
});
}
//定义一个方法用不同的方式消费同一个字符串数据
private static void printInfo(String[] stArray, Consumer<String> con1, Consumer<String> con2) {
for (String s : stArray) {
con1.andThen(con2).accept(s);
}
}
}
- Predicate接口
Predicate<T>:常用的四个方法
①boolean test(T t):对给定的参数进行判断(判断逻辑由Lambda表达式实现),返回一个布尔值
②default Predicate<T> negate():返回一个逻辑的否定,对应逻辑非
③default Predicate<T> add(Predicate other):返回一个组合的判断,对应短路与
④default Predicate<T> or(Predicate other):返回一个组合判断,对应短路或
⑤Predicate<T>接口通常用于判断参数是否满足指定的条件
import java.util.function.Predicate;
public class PredicateDemo {
public static void main(String[] args) {
//test1
boolean test = cheakString("helloworld", (String s) -> {
return s.length() > 8;
});
System.out.println(test);
//test2
boolean test3 = cheakString("helloworld",(String s)->s.length()>8,(String s)->s.length()<15);
System.out.println(test3);
//test3
}
private static boolean cheakString(String s,Predicate<String> predicate){
//return predicate.test(s);
return predicate.negate().test(s);//相当于!predicate.test(s)
}
//同一个字符串给出两个不同的判断条件,最后把这两个判断的结果做逻辑与操作
private static boolean cheakString(String s,Predicate<String> predicate1,Predicate<String> predicate2){
// boolean b1 = predicate1.test(s);
// boolean b2 = predicate2.test(s);
// boolean b3 = b1&&b2;
// return b3;
//and
// boolean test = predicate1.and(predicate1).test(s);
// return test;
//or
boolean test = predicate1.or(predicate2).test(s);
return test;
}
}
- Function接口
Function<T,R>:常用的两个方法
①R apply(T t):将此函数应用于给定的参数
②default<V> function andThen(Function after):返回一个组合函数,首先将该函数应用于输入,然后将after函数应用于结果
③Function<T,R>接口通常用于对参数进行处理,转换处理逻辑由Lambda表达式实现,然后返回一个新的值。
import java.util.function.Function;
public class FunctionDemo {
public static void main(String[] args) {
convert("200", (String s) -> {
return Integer.parseInt(s) + 100;
});
//andthen
convert("200", (String s) -> {
return Integer.parseInt(s) + 100;
},(Integer a)-> {
return String.valueOf(a);
});
}
//apply
private static void convert(String s, Function<String, Integer> function) {
int apply = function.apply(s);
System.out.println(apply);
}
//andthen
private static void convert(String s, Function<String, Integer> function1, Function<Integer, String> function2) {
// int apply = function1.apply(s);
// String ss = function2.apply(apply);
// System.out.println(ss);
String ss = function1.andThen(function2).apply(s);
System.out.println(ss);
}
}
网友评论