函数式接口是指只包含一个抽象方法的接口,除了这一个抽象方法外,它还可以有default方法和static方法。
下面这一个就是函数式接口的例子:
public interface A {
void say(String str);
}
可以使用匿名内部类实现该接口:
A a = new A() {
@Override
public void say(String str) {
System.out.println(str);
}
};
a.say("hello");
也可以使用lambda实现该接口,可以看到lambda的写法更简洁:
A a = (String str)-> System.out.println(str);
// A a = System.out::println; //还可以简写成方法引用的形式
a.say("hello");
上面的示例是先声明一个函数式接口,然后再实现它,那有没有更简单的方式呢?答案是有的,java内置了一些通用的函数式接口(在java.util.function包下),常用的有Consumer、Function、Predicate、Supplier,比如上面的例子可以写成:
Consumera = System.out.println(str); a.accept("hello");
下面来一一介绍这几个内置的函数式接口:
ConsumerConsumer代表接收一个参数、且没有返回值的操作,下面是Consumer接口的定义:
public interface Consumer{ void accept(T t); default Consumer andThen(Consumer super T> after) { Objects.requireNonNull(after); return (T t) -> { accept(t); after.accept(t); }; } }
可以看到,Consumer接口有一个accept抽象方法需要我们实现。下面的示例就是接收一个String类型的参数,然后在控制台打印该字符串(无返回值)
Consumera = (String str)-> System.out.println(str); a.accept("hello");
那还有一个andThen默认函数是干啥用的呢?其实它是用来组合函数的,可以将两个函数组合成一个新函数使用,举个例子:
ConsumerFunctiona = (String str)-> System.out.println(str.toLowerCase()); Consumer b = (String str)-> System.out.println(str.toUpperCase()); Consumer c = a.andThen(b); //先执行a,然后用同一个参数再执行b c.accept("hello");
Function代表接收一个参数、且有返回值的操作,下面是Function接口的定义:
public interface Function{ R apply(T t); default Function compose(Function super V, ? extends T> before) { Objects.requireNonNull(before); return (V v) -> apply(before.apply(v)); } default Function andThen(Function super R, ? extends V> after) { Objects.requireNonNull(after); return (T t) -> after.apply(apply(t)); } //... }
Function接口有一个apply抽象方法需要我们实现。下面的示例就是接收一个String类型的参数,然后返回拼接后的字符串
Functiona = (String str) -> "hello," + str; String result = a.apply("world"); //result的值为"hello,world"
接口定义中的默认方法compose和andThen都是用来组合函数的,两者的区别就是组合的函数执行顺序不同,看个例子就懂了:
FunctionPredicatea = (String str) -> "hello," + str; Function b = (String str) -> str.toUpperCase(); //组合函数c是先执行b,然后拿着b的返回值做为参数再执行a Function c = a.compose(b); String result1 = c.apply("world"); //result1的值为"hello,WORLD" //组合函数d是先执行a,然后拿着a的返回值做为参数再执行b Function d = a.andThen(b); String result2 = d.apply("world"); //result2的值为"HELLO,WORLD"
Predicate代表接收一个参数、且返回一个boolean值的操作,下面是Predicate接口的定义:
public interface Predicate{ boolean test(T t); default Predicate and(Predicate super T> other) { Objects.requireNonNull(other); return (t) -> test(t) && other.test(t); } default Predicate or(Predicate super T> other) { Objects.requireNonNull(other); return (t) -> test(t) || other.test(t); } //... }
Predicate接口有一个test抽象方法需要我们实现。下面是判断一个数是否小于3的例子:
PredicatelessThanThree = (Integer x)->x<3; lessThanThree.test(5); //false
接口定义中的默认方法and和or都是用来组合函数的,分别表示逻辑与、逻辑或,看个例子:
PredicateSupplierlessThanThree = (Integer x)->x<3; Predicate lessThanTen = (Integer x)->x<10; Predicate andPredicate = lessThanThree.and(lessThanTen); andPredicate.test(5); //false Predicate orPredicate = lessThanThree.or(lessThanTen); orPredicate.test(5); //true
Supplier代表无参、且有返回值的操作,下面是Supplier接口的定义:
public interface Supplier{ T get(); }
Supplier接口有一个get抽象方法需要我们实现。下面是每次调用生成一个随机数的例子:
SupplierrandomNum = ()-> (int) (Math.random() * 100); randomNum.get(); //随机一个大于等于0且小于100的数



