目录
函数式接口的由来
我们知道使用Lambda表达式的前提是需要有函数式接口,而Lambda表达式使用时不关心接口名, 抽象方法名。只关心抽象方法的参数列表和返回值类型。
public class dome {
public static void main(String[] args) {
fun((a)->{
int s = 0;
for (int i:a){
s+=i;
}
return s;
});
}
public static void fun(Operator operator ){
int[] arr={1,2,5,6,3,7};
int sum = operator.getSum(arr);
System.out.println("sum="+sum);
}
}
@FunctionalInterface
interface Operator{
int getSum(int[] arr);
}
函数式接口介绍
在JDK中帮我们提供的有很多函数式接口,主要是在 java.util.function 包中,我们重点也是介绍四个。
Supplier
无参有返回值的接口,对于的Lambda表达式需要提供一个返回数据的类型。
@FunctionalInterface
public interface Supplier<T> {
/**
* Gets a result.
*
* @return a result
*/
T get();
}
使用案例:
public class SupplierTest {
public static void main(String[] args) {
test(()->{
int[] arr={2,3,6,4,9,58,5};
Arrays.sort(arr);
return arr[arr.length-1];
});
}
public static void test(Supplier<Integer> supplier){
Integer max = supplier.get();
System.out.println("最大值为:"+max);
}
}
Consumer
有参无返回值的接口,前面介绍的Supplier接口是用来生产数据的,而Consumer接口是用来消费数据的,使用的时候需要指定一个泛型来定义参数类型
@FunctionalInterface
public interface Consumer<T> {
/**
* Performs this operation on the given argument.
*
* @param t the input argument
*/
void accept(T t);
}
使用案例:
public class ConsumerTest {
public static void main(String[] args) {
test((a)->{
System.out.println("字符串小写输出为:"+a.toLowerCase());
});
}
public static void test(Consumer<String> consumer){
consumer.accept("hELlo WoRlD");
}
}
Consumer接口中的默认方法:andThen
如果一个方法的参数和返回值全部是Consumer类型,那么就可以实现效果,消费一个数据的时候, 首先做一个操作,然后再做一个操作,实现组合,而这个方法就是Consumer接口中的default方法 andThen方法
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
使用案例:
public class ConsumerTest {
public static void main(String[] args) {
test(
(a)->{
System.out.println("字符串小写输出为:"+a.toLowerCase());
},
(b)->{
System.out.println("字符串大写输出为:"+b.toUpperCase());
});
}
public static void test(Consumer<String> consumer1,Consumer<String> consumer2){
consumer2.andThen(consumer1).accept("hELlo WoRlD");
}
}
Function
有参有返回值的接口,Function接口是根据一个类型的数据得到另一个类型的数据,前者称为前置条 件,后者称为后置条件。
@FunctionalInterface
public interface Function<T, R> {
/**
* Applies this function to the given argument.
*
* @param t the function argument
* @return the function result
*/
R apply(T t);
}
使用案例:
public class FunctionTest {
public static void main(String[] args) {
test((msg)->{
return Integer.parseInt(msg);
});
}
public static void test(Function<String,Integer> function){
Integer i = function.apply("666");
System.out.println("字符转数字:"+i);
}
}
Function接口也用一个andThen默认方法,也是用来组合操作,这里不做赘述。
Predicate
有参且返回值为Boolean的接口
@FunctionalInterface
public interface Predicate<T> {
/**
* Evaluates this predicate on the given argument.
*
* @param t the input argument
* @return {@code true} if the input argument matches the predicate,
* otherwise {@code false}
*/
boolean test(T t);
}
使用案例:
public class PredicateTest {
public static void main(String[] args) {
test((msg)->{
return msg.length()>10;
});
}
public static void test(Predicate<String> predicate){
boolean b = predicate.test("sihwhvbsce");
System.out.println("该字符串长度是否大于10:"+b);
}
}
Predicate接口中的默认方法法提供了逻辑关系操作 and or negate isEquals方法
public class PredicateTest {
public static void main(String[] args) {
test(msg1 -> {
return msg1.contains("H");
}, msg2 -> {
return msg2.contains("W");
});
}
public static void test(Predicate<String> p1, Predicate<String> p2) {
//是否 p1 包含H 同时 p2 包含W
boolean bb1 = p1.and(p2).test("Hello");
//是否 p1 包含H 或者 p2 包含W
boolean bb2 = p1.or(p2).test("Hello");
//是否 p1 不包含H
boolean bb3 = p1.negate().test("Hello");
System.out.println(bb1); // FALSE
System.out.println(bb2); // TRUE
System.out.println(bb3); // FALSE
}
}