继JDK1.8之后 为了丰富lambda的使用场景
java更新了java.util.function的包,里面放了很多函数式接口
下列接口说明均转自API文档:
-
BiConsumer<T,U> 表示接受两个输入参数并且不返回结果的操作。
BiFunction<T,U,R> 表示接受两个参数并产生结果的函数。
BinaryOperator<T> 表示对同一类型的两个操作数的操作,产生与操作数相同类型的结果。
BiPredicate<T,U> 表示两个参数的谓词(布尔值函数)。
BooleanSupplier 代表
boolean
结果。Consumer<T> 表示接受单个输入参数并且不返回结果的操作。
DoubleBinaryOperator 代表两个
double
操作数的操作,并产生一个double
结果。DoubleConsumer 表示接受单个
double
参数的操作,并且不返回任何结果。DoubleFunction<R> 表示接受双值参数并产生结果的函数。
DoublePredicate 表示一个
double
值参数的谓词(布尔值函数)。DoubleSupplier 代表
double
结果。DoubleToIntFunction 表示接受双值参数并产生int值结果的函数。
DoubleToLongFunction 表示接受双值参数并产生长期值结果的函数。
DoubleUnaryOperator 表示对一个
double
值的操作数的操作,产生一个double
值结果。Function<T,R> 表示接受一个参数并产生结果的函数。
IntBinaryOperator 表示对两个
int
操作数的操作,并产生一个int
结果。IntConsumer 表示接受单个
int
参数的操作,并且不返回任何结果。IntFunction<R> 表示一个接受int值参数并产生结果的函数。
IntPredicate 表示一个
int
值参数的谓词(布尔值函数)。IntSupplier 代表
int
结果的供应商。IntToDoubleFunction 表示接受一个int值参数并产生一个双值结果的函数。
IntToLongFunction 表示接受一个int值参数并产生一个长效结果的函数。
IntUnaryOperator 表示对单个
int
值的操作数的操作,产生一个int
结果。LongBinaryOperator 表示对两个
long
操作数的操作,并产生一个long
结果。LongConsumer 表示接受单个
long
参数的操作,并且不返回任何结果。LongFunction<R> 表示接受长期参数并产生结果的函数。
LongPredicate 表示一个
long
值参数的谓词(布尔值函数)。LongSupplier 代表
long
结果。LongToDoubleFunction 表示接受长期参数并产生双值结果的函数。
LongToIntFunction 表示接受长值参数并产生int值结果的函数。
LongUnaryOperator 表示对单个
long
值的操作数的操作,产生一个long
值结果。ObjDoubleConsumer<T> 表示接受对象值和
double
参数的操作,并且不返回任何结果。ObjIntConsumer<T> 表示接受对象值和
int
值参数的操作,并且不返回任何结果。ObjLongConsumer<T> 表示接受对象值和
long
值参数的操作,并且不返回任何结果。Predicate<T> 表示一个参数的谓词(布尔值函数)。
Supplier<T> 代表结果供应商。
ToDoubleBiFunction<T,U> 表示接受两个参数并产生双值结果的函数。
ToDoubleFunction<T> 表示产生双值结果的函数。
ToIntBiFunction<T,U> 表示一个接受两个参数并产生一个int值结果的函数。
ToIntFunction<T> 表示产生一个int值结果的函数。
ToLongBiFunction<T,U> 表示接受两个参数并产生长效结果的函数。
ToLongFunction<T> 表示产生长期效果的函数。
UnaryOperator<T> 表示对单个操作数产生与其操作数相同类型的结果的操作。
本篇文章对常用的四个函数式接口进行介绍
1.Supplier接口
用于生产数据,生产数据类型通过泛型变量决定
抽象方法:T get( ) 得到一个数据,有返回值
public static void main(String[] args) {
System.out.println(test(() -> "Supplier生产的数据"));
}
public static <T> T test(Supplier<T> sup) {
return sup.get();
}
直接使用Supplier函数式接口效果并不明显 ,部分方法会将Supplier作为方法参数
就可以利用Supplier生产数据来使用
2.Consumer接口
用于消费数据,消费数据类型通过泛型变量决定
抽象方法:void accept (T t) 消费一个数据,有参数无返回值
默认方法:andThen()
例如:单列集合中有一个forEach方法
public void forEach(Consumer<E> action)
这个方法中使用的就是Consumer作为方法参数,
每遍历了一个集合中的元素,就调用accept方法将其消费
直到所有元素都被消费完毕后,也就是遍历完毕了
ArrayList<Integer> list = new ArrayList<>();
Collections.addAll(list, 12, 412, 41, 24, 124, 1);
list.forEach(integer -> System.out.println(integer)) ;
直接使用Consumer接口效果也不明显,还是会将Consumer接口放在方法参数上使用
默认方法andThen()示例:
public static void main(String[] args) {
test((string) -> System.out.println(string + "第一个Consumer接口"), (string) -> System.out.println(string + "第二个Consumer接口"));
//输出:测试andThen方法第一个Consumer接口 测试andThen方法第二个Consumer接口
}
public static void test(Consumer<String> one, Consumer<String> two) {
one.andThen(two).accept("测试andThen方法");
}
注:andThen执行的两次方法都是根据拿到的参数进行消费的,而不是到two之后就用one的字符串来消费
3.Predicate接口
用于对某种类型的数据进行条件判断
抽象方法:boolean test (T t) 将传入的参数进行条件判断,返回boolean值
默认方法:
and(Predicate<T> other) 和
negate() 非
or(Predicate<T> other) 或
public static void main(String[] args) {
boolean b = test((string) -> string.length() > 5);
System.out.println(b); //输出:true
}
public static boolean test(Predicate<String> predicate) {
return predicate.test("测试predicate接口");
}
利用Predicate接口作方法参数,调用test方法并且使用lambda表达式,
写判断条件是字符长度是否>5,最后返回boolean值,true
negate()
public static void main(String[] args) {
boolean b = test((string) -> string.length() > 5);
System.out.println(b); //输出:false
}
public static boolean test(Predicate<String> predicate) {
return predicate.negate().test("测试predicate接口");
}
negate()就等于是java中的! 取非的值,所以最终结果为false
and()
public static void main(String[] args) {
boolean b = test((string -> string.length() > 5), (string -> string.startsWith("P")));
System.out.println(b); //输出:false
}
public static boolean test(Predicate<String> one, Predicate<String> two) {
return one.and(two).test("测试predicate接口");
}
由于"测试predicate接口"字符串满足长度大于5 却 不满足开头是P 所以返回false
相当于java中的&&
or()
public static void main(String[] args) {
boolean b = test((string -> string.length() > 5), (string -> string.startsWith("P")));
System.out.println(b); //输出:true
}
public static boolean test(Predicate<String> one, Predicate<String> two) {
return one.or(two).test("测试predicate接口");
}
由于"测试predicate接口"字符串满足长度大于5 所以返回true
相当于java中的||
4.Function接口
Function<T , R> 有两个泛型变量,用于将T类型转换为R类型
抽象方法:R apply (T t) 将传入的T类型数据转为为R类型返回
默认方法: andThen(Function<V> after)
public static void main(String[] args) {
test((string) -> Integer.parseInt(string));
System.out.println(i); //输出:2222
}
public static int test(Function<String, Integer> function) {
return function.apply("2222");
}
利用Function接口作方法参数,调用test方法
调用接口的apply方法传入"2222",最后转换成Integer类型
andThen()
public static void main(String[] args) {
int i = test((string) -> Integer.parseInt(string), (integer) -> integer + 10);
System.out.println(i); //输出:2232
}
public static int test(Function<String, Integer> one, Function<Integer, Integer> two) {
return one.andThen(two).apply("2222");
}
Function接口的andThen()方法与consumer接口的andThen()方法不一样!
Function接口中的andThen方法是使用第一次转换的结果来作第二次Function的转换
如上述例子,one接口将String类型的"2222"转换成Integer型的2222,
然后two使用已经转换成integer的2222进行加10还是返回integer型