场景
第一步创建主表数据,插入A表;第二步调用第三方接口插入B表同时更新A表的状态。此时大家应该都会想到在进行第二步的时候需要做好数据的幂等性。这样的话就会存在以下几种情况:
一、B表中不存在与A表关联的数据,此时需要调用第三方接口,插入B表同时更新A表的状态;
二、B表中存在与A表关联的数据;
A表中的状态为处理中:直接返回处理中字样;
A表中的状态为处理成功:直接返回成功的字样;
A表中的状态为处理失败:此时需要调用第三方接口,更新B表同时更新A表的状态;
伪代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| B b = this.baseMapper.selectOne(queryWrapper); if (b != null) { String status = b.getStatus(); if (Objects.equals(Constants.STATUS_ING, status)){ return "处理中"; } else if (Objects.equals(Constants.STATUS_SUCCESS, status)){ return "处理成功"; } getResponse(dto, response, s -> mapper.updateById(s)); } else { getResponse(dto, response, s -> mapper.updateById(s)); }
public void getResponse(DTO dto, Response response, Consumer<B> consumer){ ...... if (ReturnInfoEnum.SUCCESS.getCode().equals(parse.getCode())) { ...... bb.setStatus(Constants.STATUS_ING); consumer.accept(bb);
a.setStatus(Constants.STATUS_ING); aMapper.updateById(a); } }
|
函数式接口
@FunctionalInterface
@FunctionalInterface 注解用来表示该接口是函数式接口。它有助于及早发现函数式接口中出现的或接口继承的不适当的方法声明。
如果接口用该注解来注释,但实际上不是函数式接口,则会在编译时报错。
Consumer
我们一般称之为“消费者”,它表示接受单个输入参数但不返回结果的操作。不同于其它函数式接口,Consumer 预期通过副作用进行操作。
那什么又是副作用呢?说一下我所理解的副作用,副作用其实就是一个函数是否会修改它范围之外的资源,如果有就叫有副作用,反之为没有副作用。比如修改全局变量,修改输入参数所引用的对象等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @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); }; } }
|
正如我们案例中遇到的场景,我们只需要将要执行的逻辑方法当作参数传入 getResponse() 中,然后在该方法中执行 accept() 方法进行消费即可。如果还不理解,我们可以把它转换为匿名内部类的调用方式。
1 2 3 4 5 6
| getResponse(dto, response, new Consumer<B>() { @Override public void accept(B bb) { mapper.insert(bb); } });
|
当调用accept() 方法的时候就会去调用匿名内部类的方法了,也就是我们传入 getResponse() 的逻辑方法。
Supplier
我们一般称之为“生产者”,没有参数输入,但是能返回结果,为结果的提供者。
1 2 3 4 5 6 7 8
| @FunctionalInterface public interface Supplier<T> {
T get(); }
|
例:
1 2 3 4 5 6 7
| Optional<Double> optional = Optional.empty(); optional.orElseGet(()->Math.random() );
public T orElseGet(Supplier<? extends T> other) { return value != null ? value : other.get(); }
|
Function我把它称为“转换者”,表示接收一个参数通过处理之后返回一个结果的函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| @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; } }
|
我们在 lambda 表达式中应用比较多,所以我们来简单演示下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @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() 为返回处理的结果,最后输出结果为
Predicate我们称之为“判断者”,通过接收参数 T 来返回 boolean 的结果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| @FunctionalInterface 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> 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); } }
|
总结:
1 2 3 4 5 6 7 8 9
| public static void main(String[] args) { List<Teacher> list = Arrays.asList( new Teacher("张三",25), new Teacher("李四",28), new Teacher("王五",18));
list = list.stream().filter(item -> item.getAge()>25).collect(Collectors.toList()); list.stream().forEach(item->System.out.println(item.getName())); }
|