我所理解的java.util.function包

参考

https://www.cnblogs.com/linzhanfly/p/9686941.html

概述

在这里插入图片描述

consumer:函数可以作为方法入参

目的:在此之前方法的参数一直只能是具体的对象,比如int/string/obj等等,引入consumer之后,方法的参数可以是一个具体的函数了,曲线救国。源码之下无秘密。

这段代码,在main函数中创建了consumer对象,同时实现了consumer唯一的待实现方法accept,然后将它作为参数传给了test方法。
test方法接收到consumer后,中调用了consumer的accept方法,真正执行了accept方法,并给了他具体需要执行的参数。

  public static void main(String[] args) {

        //1. 声明consumer,它接收一个参数,但不返回任何值
        Consumer<Integer> consumer = v -> {
            v = v + 10;
            System.out.println(v);
        };

        //3. 传递参数consumer
        test(consumer);

    }


    //2. 定义一个方法,接收参数为consumer类型
    public static final void test(Consumer<Integer> consumer) {

          //4. 在方法内部调用consumer的具体方法,同时给consumer传入参数
        for (int i = 0; i < 10; i++) {
            if(i%2==0){
                consumer.accept(i);
            }
        }
    }

这段代码在test中遍历0-9,当遍历的数字%2==0时,给他+10,然后打印出来,运行结果如下:

10
12
14
16
18

还有点懵的同学再看看这段熟悉的代码片段,因为consumer这个接口只有一个待实现的接口方法,所以我们平时写list.foreach的时候可以直接写出lamda风格的实现类:list.foreach(v-> System::println);
如果你来定义这种接口的话,使用consumer来当入参,好处是不是不言自明了。
在这里插入图片描述

Predicate:条件使用者来定义

Predicate和consumer有异曲同工之处,也是通过接口来使函数可以接收一个“函数”作为入参,但他和consumer不同,他的作用是让传入者来决定判断的条件,还是上面那个例子:

   public static void main(String[] args) {
        Predicate<Integer> predicate = v -> v % 2 == 0;
        predicateTest(predicate);
    }

    public static final void predicateTest(Predicate<Integer> predicate) {

        for (int i = 0; i < 10; i++) {
            if(predicate.test(i)){
                System.out.println(i+10);
            }
        }
    }

我们把test方法中的判断条件,换成了使用入参predicate的test方法。运行结果如下:

10
12
14
16
18

Predicate只有一个待实现的方法,所以一样可以写成lamda风格。
再拿arraylist中的源码来举例
在这里插入图片描述
这是arralist里的条件删除方法,接收一个Predicate作为入参,这样使用者可以任意定义要删除符合什么规则的元素,使删除规则和具体的删除及便利操作解藕。
它还包含一些其他的默认实现方法,你可以选择直接用,也可以选择覆盖他们,看下这些定义,有什么想法吗:

  default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

    default Predicate<T> negate() {
        return (t) -> !test(t);
    }

    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }

    static <T> Predicate<T> isEqual(Object targetRef) {
        return (null == targetRef)
                ? Objects::isNull
                : object -> targetRef.equals(object);
    }

Function:转换逻辑交给我

Function接收一个参数,同时返回另一个类型的出参,中间的操作逻辑由定义的人自定义,他也是只有一个待实现的方法。还是上面的例子:

    public static void main(String[] args) {
         Function<Integer, Integer> funciton = (n) -> n+10;
        functionTest(funciton);

    }

    public static final void functionTest(Function<Integer, Integer> function) {

        for (int i = 0; i < 10; i++) {
            if (i % 2 == 0) {
                System.out.println(function.apply(i));
            } else {
                System.out.println(i);
            }
        }
    }

如果i%2==0,则执行function的apply方法,给i加上10,执行效果如下:

10
1
12
3
14
5
16
7
18
9

这个感觉是不是让你想起了stream流的map方法:
在这里插入图片描述

Supplier:每次都给你一个新对象

你可以把它当成一个用来创建对象的工厂,每一次get方法的调用他都会给你返回一个你定义好逻辑创建的新对象;也可以用来做使用时才加载,因为定义Supplier的时候他是不会做任何操作的,只有等到调用get,他才会执行

 public static void main(String[] args) {

        supplierTest(()->"hello world");

    }

    public static final void supplierTest(Supplier<String> supplier) {

        for (int i = 0; i < 10; i++) {
            if (i % 2 == 0) {
                System.out.println(supplier.get());
            } else {
                System.out.println(i);
            }
        }
    }

当i%==2时,返回一个“新”的字符串,hello world

hello world
1
hello world
3
hello world
5
hello world
7
hello world
9

参考:Optional.orElseGet(Supplier<? extends T>):

    public T orElseGet(Supplier<? extends T> other) {
        return value != null ? value : other.get();
    }

UnaryOperator: 同类型转换

UnaryOperator和function作用差不多,只不过他不接受入参和出参为不同类型,只能为同类型

    private static void unaryOperator() {
        UnaryOperator<Integer> unaryOperator = (n) -> n+10;
        unaryOperatorTest(unaryOperator);
    }

    public static final void unaryOperatorTest(UnaryOperator<Integer> unaryOperator) {

        for (int i = 0; i < 10; i++) {
            if (i % 2 == 0) {
                System.out.println(unaryOperator.apply(i));
            } else {
                System.out.println(i);
            }
        }
    }

可以参考arraylist的replaceall方法
在这里插入图片描述

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值