一、函数式接口
1.1 概念
函数式接口:
- 有且仅有一个
抽象方法
的接口;- Java 中的函数式编程的体现就是 Lambda 表达式;
如果检测一个接口是不是函数式接口:
- 添加 @FunctionlIterface 注释,如果接口不是函数式接口则会报错;
注:
- @FunctionlIterface 注释是可选的,即使不写这个注释,只要接口是函数式接口就可以使用 Lambda 表达式,为避免书写出现纰漏,建议加上该注释;
示例:
@FunctionalInterface public interface MyIterface { void show(); } public class MyIterfaceDemo { public static void main(String[] args) { MyIterface myIterface = ()-> System.out.println("函数式接口"); myIterface.show(); } }
1.2 函数式接口的使用
函数式接口作为方法的参数时:
- 如果方法的参数是一个函数式接口,我们可以使用 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() + ":Lambda 表达式启动线程")); } private static void startThread(Runnable r){ new Thread(r).start(); } }
函数式接口作为方法的返回值时:
- 如果方法的返回值是一个函数式接口,可以使用 Lambda 表达式作为返回结果;
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class ComparatorDemo { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("cccc"); list.add("bb"); list.add("ddd"); list.add("a"); System.out.println("排序前:" + list); Collections.sort(list,getComparator()); System.out.println("排序后:" + list); } private static Comparator<String> getComparator(){ //匿名内部类 // return new Comparator<String>(){ // @Override // public int compare(String o1, String o2) { // return o1.length() - o2.length(); // } // }; //Lambda 表达式 return (s1,s2)->s1.length()-s2.length(); } }
1.3 Supplier 接口
Supplier 包含一个无参的方法:
- T get(): 获得结果;
- 该方法不需要参数,它会按照实现的逻辑返回一个数据;
- Supplier 接口也被称为
生产型接口
;示例:
import java.util.function.Supplier; public class SupplierDemo { public static void main(String[] args) { System.out.println(getString(()->"奥特曼")); System.out.println(getString(()->45)); System.out.println(getString(()->!true)); } private static Object getString(Supplier<Object> sup){ return sup.get(); } }
注,
- 示例中指定的类型是 Object ,故所有类型数据都可以接收,若指定类型则只能接收指定类型的数据;
- Supplier 中泛型 T 所替换的类型只能是封装类,例如 String , Integer 等;
1.4 Consumer 接口:
Consumer 包含两个方法:
- void accept(T t): 对给定的参数执行操作;
示例 1:
import java.util.function.Consumer; public class CondumerDemo1 { public static void main(String[] args) { //Lambda 表达式 operatorString("张三",s-> System.out.println(s)); //方法引用 operatorString("李四", System.out::println); } private static void operatorString(String name, Consumer<String> con){ con.accept(name); } }
- default Consumer andThen(Consumer after):返回一个由
Consumer
执行此操作,在序列,其次是after
操作;示例 2 :
import java.util.function.Consumer; public class CondumerDemo2 { public static void main(String[] args) { String[] strArray = {"张三,18","李四,20","王五,19"}; printInfo( strArray, str-> System.out.print("姓名:" + str.split(",")[0]), str-> System.out.println(",年龄:" + Integer.parseInt(str.split(",")[1])) ); } private static void printInfo(String[] strArray, Consumer<String> con1, Consumer<String> con2){ for (String str : strArray) { con1.andThen(con2).accept(str); } } }
1.5 Predicate 接口
Predicate有五个方法:
- boolean test(T t):对给定的规则进行判断;
示例 1 :
import java.util.function.Predicate; public class PredicateDemo1 { public static void main(String[] args) { //结果 false System.out.println(useJudge("张三喜欢吃西瓜",s->s.length() > 8)); } private static boolean useJudge(String s, Predicate<String> pre){ return pre.test(s); } }
- default Predicate and(Predicate other): 返回短路逻辑与的判断;
示例 2 :
import java.util.function.Predicate; public class PredicateDemo2 { public static void main(String[] args) { //结果 false System.out.println(useJudge("张三喜欢吃西瓜", s->s.length() > 2, s -> s.length() < 7)); } private static boolean useJudge(String s, Predicate<String> pre1, Predicate<String> pre2){ return pre1.and(pre2).test(s); } }
- default Predicate or(Predicate other): 返回短路逻辑或的判断;
示例 3 :
import java.util.function.Predicate; public class PredicateDemo3 { public static void main(String[] args) { //结果 true System.out.println(useJudge("张三喜欢吃西瓜", s->s.length() > 2, s -> s.length() < 7)); } private static boolean useJudge(String s, Predicate<String> pre1, Predicate<String> pre2){ return pre1.or(pre2).test(s); } }
- default Predicate negate(): 返回一个表示该谓词的逻辑否定的谓词,相当于逻辑非运算;
示例 4 :
import java.util.function.Predicate; public class PredicateDemo4 { public static void main(String[] args) { //结果 true System.out.println(useJudge("张三喜欢吃西瓜",s->s.length() > 8)); } //判断给定的字符串是否满足要求 private static boolean useJudge(String s, Predicate<String> pre){ return pre.negate().test(s); } }
- static Predicate isEqual(Object targetRef):先对参数判断是否为 null ,不为 null 则进行 equals() 操作;
示例 5 :
import java.util.function.Predicate; public class PredicateDemo5 { public static void main(String[] args) { //结果 false System.out.println(useJudge("张三喜欢吃西瓜","张三不喜欢吃西瓜")); } private static boolean useJudge(String s1, String s2){ return Predicate.isEqual(s1).test(s2); } }
1.6 Function 接口
Function<T,R>:常用的有两个方法
- R apply(T t):将此函数应用于给定的参数;
示例 1 :
import java.util.function.Function; public class FunctionDemo { public static void main(String[] args) { //Lambda 表达式 convert("123",s->Integer.parseInt(s)); //方法引用 convert("123",Integer::parseInt); } private static void convert(String s, Function<String,Integer> fun){ System.out.println(fun.apply(s)); } }
- defaultFunction andThen( Function after ):返回一个由功能首次采用该函数的输入,然后将
after
函数的结果;示例 2 :
import java.util.function.Function; public class FunctionDemo { public static void main(String[] args) { toConvert( "100", s -> Integer.parseInt(s), s -> String.valueOf(s + 25) ); } private static void toConvert(String s, Function<String,Integer> fun1,Function<Integer,String> fun2){ System.out.println(fun1.andThen(fun2).apply(s)); } }