标注为FunctionalInterface的接口被称为函数式接口,该接口只能有一个自定义方法,但是可以包括从object类继承而来的方法。如果一个接口只有一个方法,则编译器会认为这就是一个函数式接口。是否是一个函数式接口,需要注意的有以下几点:
/**
* 一个入参,和一个返回参数
*/
R apply(T t);
/**
* 返回一个先执行before函数对象apply方法再执行当前函数对象apply方法的函数对象
*/
default Function compose(Function super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
/**
* 返回一个先执行当前函数对象apply方法再执行after函数对象apply方法的函数对象。
*/
default Function andThen(Function super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
/**
* 返回一个函数,此函数入参值是什么,出参为什么
*/
static Function identity() {
return t -> t;
}
Arrays::asList
package com.lin.function.function;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
public class TestFunction {
public static void main(String[] args) {
Function func1 = e->e*2;
Function func2 = e->e+2;
System.out.println(func2.andThen(func1).apply(3));
System.out.println(func2.compose(func1).apply(3));
List list = new ArrayList();
String[] a = {"a1","a2","a3"};
String[] b = {"b1","b2"};
String[] c = {"c1","c2","c3"};
list.add(a);
list.add(b);
list.add(c);
list.stream().map(Arrays::asList).forEach(System.out::println);
}
}
Function接口是一个入参,一个出参。
1) 当入参和出参为基本类型int、long和double,会新增12种扩展
① 入参为基本类型,出参为自定义
IntFunction:入参为int,出参自定义,以此类推,LongFunction和DoubleFunction
② 入参为自定义,出参为基本类型
ToIntFunction:出参为int,入参自定义,以此类推,ToLongFunction和ToDoubleFunction
③ 入参和出参都为基本类型
IntToDoubleFunction:入参为int,出参为double,以此类推IntToLongFunction、LongToIntFunction、LongToDoubleFunction、DoubleToIntFunction、DoubleToLongFunction
2) 当入参为2个,出参为1个,新增4种扩展
BiFunction:入参2个,出参1个
ToIntBiFunction:入参2个自定义,出参为int,以此类推ToIntLongFunction和ToDoubleBiFunction
/**
* 一个入参,出参为boolean类型
*/
boolean test(T t);
/**
*且操作,既满足A也满足B条件
*/
default Predicate and(Predicate super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
/**
*取反操作 为true则返回false
*/
default Predicate negate() {
return (t) -> !test(t);
}
/**
*或操作,满足A条件或者满足B条件
*/
default Predicate or(Predicate super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
/**
*静态方法,判定是否相等
*/
static Predicate isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
Collection::isEmpty
package com.lin.function.predicate;
import java.util.function.Predicate;
public class TestPredicate {
public static void main(String[] args) {
Predicate p1 = e->e<10;//小于10的条件
Predicate p2 = e->e>5;//大于5的条件
System.out.println(p1.and(p2).test(8));
System.out.println(p1.or(p2).test(8));
System.out.println(p1.negate().test(8));
}
}
Predicate接口是一个入参,出参boolean。
1) 当入参为基本类型int、long和double,会新增3种扩展
IntPredicate表示入参为int。以此类推LongPredicate和DoublePredicate。
2) 当入参为2个时,会新增1种扩展
BiPredicate。
/**
一个入参,没有出参接口
*/
void accept(T t);
/**
* 返回一个先执行当前函数对象apply方法再执行after函数对象apply方法的函数对象。
*/
default Consumer andThen(Consumer super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
System.out::println
package com.lin.function.consumer;
import java.util.function.Consumer;
public class TestConsumer {
public int a = 1;
public static void main(String[] args) {
Consumer consumer1 = e-> e.a = e.a+1;
Consumer consumer2 = e-> e.a = e.a*2;
TestConsumer old = new TestConsumer();
old.a = 1;
consumer1.accept(old);
System.out.println(old.a);
consumer1.andThen(consumer2).accept(old);
System.out.println(old.a);
}
}
Consumer接口是一个入参,没有出参。
1) 当入参为基本类型int、long和double,会新增3种扩展
IntConsumer,入参为int。以此类推,LongConsumer和DoubleConsumer。
2) 当入参2个,分别是一个泛型和一个基本类型int、long和double,会新增3种扩展
ObjIntConsumer,入参为泛型T和int。以此类推,ObjLongConsumer和ObjDoubleConsumer。
3) 当入参2个,分别都是泛型,会新增1种扩展
BiConsumer,入参为2个,都为泛型。
/**
* 一个泛型出参,没有入参
*/
T get();
Instant::now
package com.lin.function.supplier;
import java.util.function.Supplier;
public class TestSupplier {
public static void main(String[] args){
Supplier sup = ()->"abc";
System.out.println(sup.get());
}
}
Supplier是一个只有出参,没有入参接口。
当出参是基本数据类型boolean、int、long、double时,有4种扩展分别是BooleanSupplier、IntSupplier、LongSupplier和DoubleSupplier。
UnaryOperator接口继承了Function接口,也是一个入参一个出参。特殊的地方是UnaryOperator接口的入参和出参是同一类型。
public interface UnaryOperator extends Function
/**
* 入参和出参都是同一个类型
*/
T apply(T t);
String::toLowerCase
package com.lin.function.unaryOperator;
import java.util.function.UnaryOperator;
public class TestUnaryOperator {
public static void main(String[] args) {
UnaryOperator uop1 = e-> e+3;
UnaryOperator uop2 = e-> e*2;
System.out.println(uop1.andThen(uop2).apply(2));
System.out.println(uop1.compose(uop2).apply(2));
System.out.println(UnaryOperator.identity().apply(2));
}
}
UnaryOperator接口是一个入参和一个出参,入参和出参是同一种类型。当类型为基本类型int、long和double时,有三种扩展,分别是IntUnaryOperator、LongUnaryOperator和DoubleUnaryOperator。
BinaryOperator接口继承BiFunction接口,BiFunction接口是Function接口的扩展,有2个入参和1个出参。BinaryOperator接口是BiFunction接口的特殊情况,当入参和出参的数据类型相同时,就是BinaryOperator。
public interface BinaryOperator extends BiFunction
除了继承BiFunction接口里面的方法外,BinaryOperator接口还实现一下2个静态方法:
/**
* 接收一个比较实现,获取最小值。
*/
public static BinaryOperator minBy(Comparator super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
}
/**
*接收一个比较实现,获取最大值。
*/
public static BinaryOperator maxBy(Comparator super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
}
BigInteger::add
package com.lin.function.binaryOperator;
import java.util.function.BinaryOperator;
public class TestBinaryOperator {
public static void main(String[] args) {
BinaryOperator addOperator = (a,b)->a+b;
BinaryOperator subOperator = (a,b)->a-b;
System.out.println(addOperator.apply(4, 2));
System.out.println(subOperator.apply(4, 2));
System.out.println(BinaryOperator.maxBy((Integer a, Integer b)->a.compareTo(b)).apply(4, 5));
System.out.println(BinaryOperator.minBy((Integer a, Integer b)->a.compareTo(b)).apply(4, 5));
}
}
BinaryOperator有2个入参和1个出参,而且入参和出参的数据类型一样。如果数据类型为基本类型int、long和double时,有3种扩展,分别是IntBinaryOperator、LongBinaryOperator和DoubleBinaryOperator。