java-lambda(三):jdk 内置函数式接口

本文中所有的函数式接口均位于(java.util.function) 包下。

目录

四大内置核心函数式接口

基于四大内置核心函数式接口的其它衍生接口

四大核心内置函数式接口详解与使用示例

一:Consumer

二:Supplier

三:Function 与 BiFunction,>,>

function 传递行为的demo

多个 function 的串联操作

四:Predicate

与操作,或操作,非操作

方法引用



四大内置核心函数式接口

基于四大内置核心函数式接口的其它衍生接口

四大核心内置函数式接口详解与使用示例

一:Consumer<T>

这是一个函数式接口,被@FunctionalInterface 注解所申明的。该接口表示接受单个输入参数且不返回任何结果的操作。与大多数其它的功能不同的是,这个接口本身带有副作用,他可能修改所接收的参数(引用是不可变的,但是引用的对象中的数据是有可能被更改的)。它的函数式方法名字叫做 accept。

public class DemoConsumer {
    public static void main(String[] args) {
        DemoConsumer demoConsumer = new DemoConsumer();
        demoConsumer.consumerDemoMethod("123", string -> System.out.println(string));

        // 无论做什么操作, 只要不返回值, 哪怕是没有任何的主体都可以
        demoConsumer.consumerDemoMethod("123", string -> {
        });

        // Consumer 在 jdk 中广泛应用于各大集合的 foreach 方法:
        new ArrayList<String>().forEach(t -> System.out.println(t));
        new ConcurrentHashMap<String, String>().forEach((key, value) -> System.out.println(key +", " + value));
    }

    public void consumerDemoMethod(String t, Consumer<String> par) {
        par.accept(t);
    }
}

 

二:Supplier<T>

这是一个函数式接口, 其函数式方法为 get,表示结果的提供者。它并不要求每一次的返回都是新的,也就是说只要有任意的返回都可以。它是不接收任何参数并返回一个任意的结果。

public class DemoSupplier {
    public static void main(String[] args) {
        Supplier<String> stringSupplier = new Supplier<String>() {
            @Override
            public String get() {
                return "aa";
            }
        };

        // 上方代码等价于
        stringSupplier = () -> "aa";
        System.out.println(stringSupplier.get());
    }
}

 

三:Function<T, R> 与 BiFunction<T, U, R>

Function 代表一个函数,这个函数接收一个参数并且生成一个结果。这是一个函数式接口,其接口中的函数式方法为 apply(T t),而 BiFunction 与 Function 类似,只是它(BiFunction )接收两个参数,而只返回一个结果。

function 传递行为的demo

public class DemoFunction {
    public static void main(String[] args) {
        System.out.println(compute(1, integer -> 2 * integer));
        System.out.println(compute(1, integer -> {return  (2 + integer);}));
    }

    public static int compute(int req, Function<Integer, Integer> function) {
        return function.apply(req);
    }
}

多个 function 的串联操作

多个 function 的串联操作实际上是利用 function 接口内部提供的两个静态方法 compose 和 andThen(BiFunction 里面只有andThen),它们比较难以理解,示例代码如下

public class DemoFunction {
    public static void main(String[] args) {
        System.out.println(testCompose("输入 ", result -> result + " function1 的返回值", result -> result + " function2 的返回值"));
        System.out.println(testCompose("输入 ", result -> result + " function1 的返回值", result -> result + " function2 的返回值",
                result -> result + " function3 的返回值"));
        System.out.println(testAndThen("输入 ", result -> result + " function1 的返回值", result -> result + " function2 的返回值"));
    }

    /**
     * 多个 function 的串联操作, compose方法是当前的this.function对象接收一个新的new function对象,并且
     * 新的 new function 对象的操作会在 this.function 对象执行之前执行,也就是说 function2 会在 function1
     * 之前进行执行.
     */
    public static String testCompose(String req, Function<String, String> function1, Function<String, String> function2) {
        return function1.compose(function2).apply(req);
    }

    public static String testCompose(String req, Function<String, String> function1, Function<String, String> function2, Function<String, String> function3) {
        return function1.compose(function2).compose(function3).apply(req);
    }

    /**
     * 多个 function 的串联操作, andThen 方法理解成为compose相反操作即可.
     */
    public static String testAndThen(String req, Function<String, String> function1, Function<String, String> function2) {
        return function1.andThen(function2).apply(req);
    }

    public static String testAndThen(String req, Function<String, String> function1, Function<String, String> function2, Function<String, String> function3) {
        return function1.andThen(function2).apply(req);
    }
}

 

四:Predicate<T>

函数式接口,表示一个参数的谓词(判断)。是一个 布尔值的接口,其函数式方法是 test。

public class DemoPredicate {
    public static void main(String[] args) {
        // 构建一个谓词,用来判断条件是否满足
        Predicate<String> predicate = p -> p.length() > 5;
        // 调用test方法之后,判断值的长度是否大于5
        System.out.println(predicate.test("一个参数"));
    }
}

与操作,或操作,非操作

与或非三个操作实际上是使用了 Predicate 接口中提供的三个静态方法(与,and;或,or;非,negate).

public class DemoPredicate {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);

        Predicate<Integer> a = i -> i > 5;
        Predicate<Integer> b = i -> i % 2 == 0;
        // 逻辑与操作, 只有当 a 和 b 都为true的时候, 值才输出
        list.stream().filter(a.and(b)).forEach(System.out::println);
        System.out.println("--------------------------------------");

        // 逻辑或操作, 当 a 和 b 任意值为true的时候, 值会输出
        list.stream().filter(a.or(b)).forEach(System.out::println);
        System.out.println("--------------------------------------");

        // 逻辑非操作, 也就是取反, 当值为true的时候, 输出false
        list.stream().filter(a.negate()).forEach(System.out::println);
    }
}

方法引用

内置函数式接口通用的核心只有这四个,其余的都是基于它们的衍生(比如上文中的 Function 与 BiFunction),接下来需要看的是方法引用。

java-lambda(四):方法引用

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值