如果还不懂如何使用 Consumer 接口,来公司我当面给你讲!(三)

642 阅读3分钟

「这是我参与11月更文挑战的第19天,活动详情查看:2021最后一次更文挑战」。

上文中我们介绍了 Supplier 的使用方法,本文我们来看看 Consumer 和 Function 的源代码与使用情况。

Consumer

我们一般称之为“消费者”,它表示接受单个输入参数但不返回结果的操作。不同于其它函数式接口,Consumer 预期通过副作用进行操作。

那什么又是副作用呢?说一下我所理解的副作用,副作用其实就是一个函数是否会修改它范围之外的资源,如果有就叫有副作用,反之为没有副作用。比如修改全局变量,修改输入参数所引用的对象等。

@FunctionalInterface
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); };
    }
}

方法解析:

  • test:对给定的参数执行此操作。
  • andThen:返回一个组合的 Consumer ,依次执行此操作,然后执行after操作。如果执行任一操作会抛出异常,它将被转发到组合操作的调用者。如果执行此操作会引发异常,则不会执行after操作。

正如我们案例中遇到的场景,我们只需要将要执行的逻辑方法当作参数传入 getResponse() 中,然后在该方法中执行 accept() 方法进行消费即可。如果还不理解,我们可以把它转换为匿名内部类的调用方式。

 getResponse(dto, response, new Consumer<B>() {
    @Override
    public void accept(B bb) {
      mapper.insert(bb);
    }
});

当调用accept() 方法的时候就会去调用匿名内部类的方法了,也就是我们传入 getResponse() 的逻辑方法。

Function

我把它称为“转换者”,表示接收一个参数通过处理之后返回一个结果的函数。

@FunctionalInterface
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));
    }

   
    static <T> Function<T, T> identity() {
        return t -> t;
    }
}

方法解析:

  • apply:将 T 类型的参数传入,经过函数表达式的计算,返回 R 类型的结果;
  • compose:返回一个组合函数,先将参数应用于 before 函数,然后将结果应用于当前函数,返回最终结果。如果对任一函数的求值引发异常,则会将其转发给组合函数的调用方。
  • andThen:返回一个组合函数,先将参数应用与当前函数,然后将结果应用于 after 函数,返回最终的结果。如果对任一函数的求值引发异常,则会将其转发给组合函数的调用方。
  • identity:返回始终返回其输入参数的函数。

我们在 lambda 表达式中应用比较多,所以我们来简单演示下:

@Data
@AllArgsConstructor
public class Teacher {
    private String name;
    private int age;
}

public class TeacherTest {
    public static void main(String[] args) {
       List<Teacher> list = Arrays.asList(
            new Teacher("张三",25),
            new Teacher("李四",28),
            new Teacher("王五",18));
      List<String> collect = list.stream().map(item -> item.getName()).collect(Collectors.toList());
      System.out.println(collect);
    }
}

其中 map 接收的参数就是 Function 类型, item 为传入参数,item.getName() 为返回处理的结果,最后输出结果为

[张三, 李四, 王五]

看到这,Consumer 和 Function 的使用方法相信你一定是掌握了吧!如果你有不同的意见或者更好的idea,欢迎联系阿Q,添加阿Q可以加入技术交流群参与讨论呦!