函数式接口定义且只定义了一个抽象方法。函数式接口很有用, 因为抽象方法的签名可以描述Lambda表达式的签名。函数式接口的抽象方法的签名称为函数描 述符。所以为了应用不同的Lambda表达式,你需要一套能够描述常见函数描述符的函数式接口。 Java API中已经有了几个函数式接口,比如:Comparable、Runnable和 Callable都是函数式接口。
在Java 8的库java.util.function包中引入了几个新的函数式接口 比较常用的有 Supplier、Consumer、Predicate、Function
一、Supplier
java.util.function.Supplier接口仅包含一个无参的方法:T get(),用来获取一个泛型参指定类型的对象数据。
实例1:使用Supplier接口调用他的get方法,返回一个字符串。
//使用Lambda表达式对他进行输出
String s = printString( () -> {
return "你好啊!";
});
System.out.println(s);
}
//使用Supplier接口调用他的get的方法,让他返回一个字符串。
public static String printString(Supplier<String> res){
return res.get();
}
实例2:求数组的最大值:
int[] arr={12,30,89,45,666,100};
int maxResult =numMax(()->{
int max=arr[0];
for (int j=1;j<arr.length;j++){
if(arr[j]>max){
max=arr[j];
}
}
return max;
});
System.out.println(maxResult);
//使用Supplier接口调用他的get的方法,计算最值
public static int numMax(Supplier<Integer> res){
return res.get();
}
二、Consumer
java.util.function.Consumer定义了一个名叫accept的抽象方法,它接受泛型T 的对象,没有返回(void)。你如果需要访问类型T的对象,并对其执行某些操作,就可以使用 这个接口。比如,你可以用它来创建一个forEach方法,接受一个Integers的列表,并对其中 每个元素执行操作。在下面的代码中,你就可以使用这个forEach方法,并配合Lambda来打印 列表中的所有元素。
2.1 抽象方法 accept()
public static <T> void foreach(List<T> list,Consumer<T> action){
for (T t:list) {
action.accept(t);
}
}
List<Integer> val= Arrays.asList(1, 2, 5, 6, 8, 66, 30 );
foreach(val,System.out::println);
2.2、Consumer的默认方法andThen进行对字符串进行消费
printInfo("HelloWord",
(s)->System.out.println(s.toUpperCase()),
(s1)->System.out.println( s1.toLowerCase()));
//给定一个字符串先进行andThen方法组合再使用accept方法进行消费。
public static void printInfo(String str,Consumer<String> c1,Consumer<String>c2 ){
//可以使用 c1.accept, c2.accept() 进行消费
c1.andThen(c2).accept(str);
}
三、Predicate
java.util.function.Predicate接口定义了一个名叫test的抽象方法,它接受泛型 T对象,并返回一个boolean。这恰恰和你先前创建的一样,现在就可以直接使用了。在你需要 表示一个涉及类型T的布尔表达式时,就可以使用这个接口、如下所示。
3.1抽象方法 test()
//定义一个方法用于测试Predicate接口 test()方法 的用处
public static boolean method(String strName,Predicate<String> str){
return str.test(strName);
}
//定义一个字符串
String str="Helloword";
//判断字符长度是否大于五
boolean isok = method( str, (s) -> s.length() > 5 );
//判断是否存在某个字符
boolean res=method(str,(s)->s.contains("Hf"));
System.out.println(isok);//true
System.out.println(res);//false
3.2、默认方法:and()==>&& 默认 方法 Or() ==> ||
//定义一个字符串
String str="Helloword";
//判断字符长度是否大于五 && 判断是否存在某个字符
boolean isokand=andMethod(str,(s)->s.length()>5,(s1)-> s1.contains("H"));
//判断字符长度是否大于10 && 判断是否存在某个字符
boolean isokand2=andMethod(str,(s)->s.length()>10,(s1)-> s1.contains("H"));
//定义一个方法用于测试Predicate接口 and用法
public static boolean andMethod(String strName,Predicate<String>str1,Predicate<String>
str2){
return str1.and(str2).test(strName);
}
==========================Or()方法=================
//定义一个方法用于测试Predicate接口 or()用法
public static boolean orMethod(String strName,Predicate<String>str1,Predicate<String>
str2){
return str1.or(str2).test(strName);
}
boolean isokand3=orMethod(str,(s)->s.length()>10,(s1)-> s1.contains("H"));
System.out.println(isokOr);//true
4、Function
java.util.function.Function接口定义了一个叫作apply的方法,它接受一个 泛型T的对象,并返回一个泛型R的对象。如果你需要定义一个Lambda,将输入对象的信息映射 到输出,就可以使用这个接口
4.1、抽象方法 apply()
public static void main(String[] args) {
//String 转 Integer 转换后 数字+10
Integer num = applyMethod( "10", (value) ->Integer.parseInt(value)+20);
System.out.println(num);//30
//计算集合中字符长度
List<Integer> map = map( Arrays.asList( "lambdas", "in", "action" ), s -> s.length());
map.forEach(System.out::println);//[7, 2, 6]
}
//测试Function 接口的 apply方法
public static Integer applyMethod(String strName, Function<String,Integer> func){
return func.apply(strName);
}
//测试Function 接口的 apply方法
public static <T,R> List<R> map(List<T> list,Function<T,R> func){
List<R> res=new ArrayList<>();
for (T t : list) {
res.add(func.apply(t));
}
return res;
}
4.2、默认方法:compose() && andThen()
//测试 compose 方法
public static Integer composeMethod(int num,Function<Integer,Integer>function1,
Function<Integer,Integer> function2){
return function1.compose(function2).apply(num);
}
//测试andThen 方法
public static Integer andThenMethod(int num,Function<Integer,Integer>function1,
Function<Integer,Integer> function2){
return function1.andThen(function2).apply(num);
}
Integer num1 = composeMethod( 3, value -> value * 4, value -> value * value );
Integer num2 = andThenMethod( 3, value -> value * 4, value -> value * value );
System.out.println(num1); //36
System.out.println(num2); //144