函数式接口是只有一个抽象方法的接口,但是可以有多个静态方法和默认方法。
静态方法不能被子类继承,默认方法可以被子类继承重写。
@FunctionalInterface 注解是非必需的,但是该注解会对函数式接口的方法进行校验,存在多个抽象方法时会编译错误,当接口继承的父接口中存在多个未实现的抽象类时,也会编译错误,因此建议写上。
文章目录
实现一个函数式接口
创建接口
@FunctionalInterface
interface Interface1{
String test(int i);
default int add(int x,int y){
return x+y;
}
}
@FunctionalInterface
interface Interface2{
String test(int i);
default int add(int x,int y){
return x+y+1;
}
}
//两个父接口的抽象方法必须一样,否则会编译错误
@FunctionalInterface
interface Interface3 extends Interface1,Interface2{
@Override
default int add(int x, int y) {
return Interface1.super.add(x,y);
}
default void print(String test) {
System.out.println(test);
}
default int get() {
return 0;
}
}
实现接口并调用
Interface3 i3 = new Interface3() {
@Override
public String test(int i) {
return String.valueOf(i*2);
}
};
//上面的实现可以用lambda简化为
//Interface3 i3 = i->String.valueOf(i*2);
System.out.println(i3.test(12));
System.out.println(i3.add(1,2));
System.out.println(i3.get());
i3.print("测试一下");
结果:
24
3
0
测试一下
java.util.function 提供的函数式接口
Function<T,R> 功能型函数
** 接受类型 T 的参数,返回类型 R 的参数**
Function<Integer,String> function = i-> "这个数字是:"+i;
System.out.println(function.apply(6));
结果:
这个数字是:6
java.util.function还提供了已经定义好类型的函数式接口。例如:
- IntFunction 接收一个 int 类型的参数,返回 R 类型的参数
IntFunction<String> function = i-> "这个数字是:"+i; System.out.println(function.apply(6)); 结果: 这个数字是:6
- ToDoubleFunction 接收一个 T 类型的参数,返回 Double 类型的参数
ToDoubleFunction<String> function = i-> Double.valueOf(i); System.out.println(function.applyAsDouble("6")); 结果: 6.0
- IntToDoubleFunction 接收一个 int 类型的参数,返回 Double 类型的参数
IntToDoubleFunction function = i-> Double.valueOf(i); System.out.println(function.applyAsDouble(6)); 结果: 6.0
其他类型的函数式接口也有与之类似的接口。
Predicate<T> 断言函数
** 接收 T 类型,返回boolean**
Predicate<Integer> intPredicate = i->i>0;
System.out.println(intPredicate.test(6));
结果:
true
Consumer<T> 消费者函数
** 消费者顾名思义只消费,不生产,接收 T 类型不返回结果**
Consumer<Integer> intComsumer = i-> System.out.println("结果是:"+i);
intComsumer.accept(1);
结果:
结果是:1
Supplier<R>提供者函数
** 与消费者函数相反,他不接收参数,返回 R 类型结果**
Supplier<Integer> supplier = ()-> 0;
System.out.println(supplier .get());
结果:
0
BiFunction<T, U, R>
接受两个参数 类型 T ,U 返回 类型 R 结果
BiFunction<Integer,Integer,String> supplier = (x,y)-> String.valueOf(x+y);
System.out.println(supplier .apply(1,1));
结果:
2
UnaryOperator<T> 一元运算函数
其实就是继承自 Function<T,T> ,输入输出类型一致
@FunctionalInterface
public interface UnaryOperator<T> extends Function<T, T> {
/**
* Returns a unary operator that always returns its input argument.
*
* @param <T> the type of the input and output of the operator
* @return a unary operator that always returns its input argument
*/
static <T> UnaryOperator<T> identity() {
return t -> t;
}
}
方法引用
创建Dog实例
class Good{
private String name = "小浣熊干脆面";
private static int allNum = 100;
public Good(String name){
this.name = name;
}
//售罄
public static void saleout(Good good){
System.out.println(good + "卖光了");
}
//出售
public int sale(int num ){
System.out.println(name+"卖出了"+num+"袋");
this.allNum-=num;
return this.allNum;
}
@Override
public String toString() {
return this.name;
}
}
静态方法的方法引用
Consumer<Good> consumer = Good::saleout;
consumer.accept(new Good("小浣熊"));
结果:
小浣熊卖光了
非静态方法实例化引用
IntUnaryOperator consumer2 = new Good("小浣熊")::sale;
System.out.println(consumer2.applyAsInt(9));
结果:
小浣熊卖出了9袋
91
非静态方法通过类引用
BiFunction<Good,Integer,Integer> consumer3 = Good::sale;
System.out.println(consumer3.apply(new Good("小浣熊"),9));
结果:
小浣熊卖出了9袋
91