Java函数式接口

函数式接口是指只包含一个抽象方法的接口,除了这一个抽象方法外,它还可以有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,比如上面的例子可以写成:

Consumer<String> a = System.out.println(str);
a.accept("hello");

下面来一一介绍这几个内置的函数式接口:

Consumer

Consumer代表接收一个参数、且没有返回值的操作,下面是Consumer接口的定义:

public interface Consumer<T> {
    void accept(T t);
    
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

可以看到,Consumer接口有一个accept抽象方法需要我们实现。下面的示例就是接收一个String类型的参数,然后在控制台打印该字符串(无返回值)

Consumer<String> a = (String str)-> System.out.println(str);
a.accept("hello");

那还有一个andThen默认函数是干啥用的呢?其实它是用来组合函数的,可以将两个函数组合成一个新函数使用,举个例子:

Consumer<String> a = (String str)-> System.out.println(str.toLowerCase());
Consumer<String> b = (String str)-> System.out.println(str.toUpperCase());
Consumer<String> c = a.andThen(b); //先执行a,然后用同一个参数再执行b
c.accept("hello"); 
/**
* 打印结果为:
* hello
* HELLO
*/

Function

Function代表接收一个参数、且有返回值的操作,下面是Function接口的定义:

public interface Function<T, R> {
    R apply(T t);
    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }
     default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }
    //...
}

Function接口有一个apply抽象方法需要我们实现。下面的示例就是接收一个String类型的参数,然后返回拼接后的字符串

Function<String, String> a = (String str) -> "hello," + str;
String result = a.apply("world"); 
//result的值为"hello,world"

接口定义中的默认方法compose和andThen都是用来组合函数的,两者的区别就是组合的函数执行顺序不同,看个例子就懂了:

Function<String, String> a = (String str) -> "hello," + str;
Function<String, String> b = (String str) -> str.toUpperCase();
//组合函数c是先执行b,然后拿着b的返回值做为参数再执行a
Function<String, String> c = a.compose(b); 
String result1 = c.apply("world"); //result1的值为"hello,WORLD"
//组合函数d是先执行a,然后拿着a的返回值做为参数再执行b
Function<String, String> d = a.andThen(b);
String result2 = d.apply("world"); //result2的值为"HELLO,WORLD"

Predicate

Predicate代表接收一个参数、且返回一个boolean值的操作,下面是Predicate接口的定义:

public interface Predicate<T> {
    boolean test(T t);
    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }
    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }
    //...
}

Predicate接口有一个test抽象方法需要我们实现。下面是判断一个数是否小于3的例子:

Predicate<Integer> lessThanThree =  (Integer x)->x<3;
lessThanThree.test(5); //false

接口定义中的默认方法and和or都是用来组合函数的,分别表示逻辑与、逻辑或,看个例子:

Predicate<Integer> lessThanThree =  (Integer x)->x<3;
Predicate<Integer> lessThanTen =  (Integer x)->x<10;
Predicate<Integer> andPredicate = lessThanThree.and(lessThanTen);
andPredicate.test(5); //false
Predicate<Integer> orPredicate = lessThanThree.or(lessThanTen);
orPredicate.test(5); //true

Supplier

Supplier代表无参、且有返回值的操作,下面是Supplier接口的定义:

public interface Supplier<T> {
    T get();
}

Supplier接口有一个get抽象方法需要我们实现。下面是每次调用生成一个随机数的例子:

Supplier<Integer> randomNum = ()-> (int) (Math.random() * 100);
randomNum.get(); //随机一个大于等于0且小于100的数
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值