一、前言
最近回顾了一下java8语法,其中发现了一个很有意思的一对逆运算接口:
- Supplier:这个接口是用来创建对象的,最大的特点是懒加载。
- Supplier接口源码
@FunctionalInterface public interface Supplier<T> { /** * Gets a result. * * @return a result */ T get(); }
- 调用方法
@Setter @Getter @NoArgsConstructor @AllArgsConstructor @ToString(callSuper = true) @EqualsAndHashCode(callSuper = false) public class Sign { private String alg; private String value; private String cert; public static void main(String[] args) { ////创建Supplier容器,声明为TestSupplier类型,此时并不会调用对象的构造方法,即不会创建对象 Supplier<Sign> sign = Sign::new; //调用get()方法,此时会调用对象的构造方法,即获得到真正对象 System.out.println(sign.get()); } }
打印结果:Sign(super=com.infosec.ra.entity.Sign@5750a, alg=null, value=null, cert=null)
- Consumer:顾名思义,这是一个对象消费者
- Consumer接口源码
@FunctionalInterface public interface Consumer<T> { //接收一个参数 void accept(T t); //调用者方法执行完后再执行after的方法 default Consumer<T> andThen(Consumer<? super T> after) { Objects.requireNonNull(after); return (T t) -> { accept(t); after.accept(t); }; } }
- 调用方法
import java.util.function.Consumer; public class ConsumerTest { public static void main(String[] args) { Consumer<Integer> consumer = (x)->{ int num = x * 1; System.out.println(num); }; Consumer<Integer> consumer1 = (x) -> { int num = x * 2; System.out.println(num); }; consumer.andThen(consumer1).accept(1); } }
==执行结果为:10 20,说明先执行consumer的方法,然后再执行consumer1的方法。==
二、利用Supplier和Consumer构建java8通用Builder
- Builder代码示例(本文核心)
import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; import java.util.function.Supplier; /** * @author Javacfox */ public class Builder<T> { private final Supplier<T> instantiator; private List<Consumer<T>> modifiers = new ArrayList<>(); public Builder(Supplier<T> instant) { this.instantiator = instant; } public static <T> Builder<T> of(Supplier<T> instant) { return new Builder<>(instant); } public <P1> Builder<T> with(Consumer1<T, P1> consumer, P1 p1) { Consumer<T> c = instance -> consumer.accept(instance, p1); modifiers.add(c); return this; } public <P1, P2> Builder<T> with(Consumer2<T, P1, P2> consumer, P1 p1, P2 p2) { Consumer<T> c = instance -> consumer.accept(instance, p1, p2); modifiers.add(c); return this; } public <P1, P2, P3> Builder<T> with(Consumer3<T, P1, P2, P3> consumer, P1 p1, P2 p2, P3 p3) { Consumer<T> c = instance -> consumer.accept(instance, p1, p2, p3); modifiers.add(c); return this; } public <P1, P2, P3,P4> Builder<T> with(Consumer4<T, P1, P2, P3,P4> consumer, P1 p1, P2 p2, P3 p3,P4 p4) { Consumer<T> c = instance -> consumer.accept(instance, p1, p2, p3,p4); modifiers.add(c); return this; } public <P1, P2, P3,P4,P5> Builder<T> with(Consumer5<T, P1, P2, P3,P4,P5> consumer, P1 p1, P2 p2, P3 p3,P4 p4,P5 p5) { Consumer<T> c = instance -> consumer.accept(instance, p1, p2, p3,p4,p5); modifiers.add(c); return this; } public T build() { T value = instantiator.get(); modifiers.forEach(modifier -> modifier.accept(value)); modifiers.clear(); return value; } /** * 1 参数 Consumer */ @FunctionalInterface public interface Consumer1<T, P1> { /** * 接收参数方法 * @param t 对象 * @param p1 参数二 */ void accept(T t, P1 p1); } /** * 2 参数 Consumer */ @FunctionalInterface public interface Consumer2<T, P1, P2> { /** * 接收参数方法 * @param t 对象 * @param p1 参数一 * @param p2 参数二 */ void accept(T t, P1 p1, P2 p2); } /** * 3 参数 Consumer */ @FunctionalInterface public interface Consumer3<T, P1, P2, P3> { /** * 接收参数方法 * @param t 对象 * @param p1 参数一 * @param p2 参数二 * @param p3 参数三 */ void accept(T t, P1 p1, P2 p2, P3 p3); } @FunctionalInterface public interface Consumer4<T, P1, P2, P3, P4>{ /** * 接收参数方法 * @param t 对象 * @param p1 参数一 * @param p2 参数二 * @param p3 参数三 * @param p4 参数四 */ void accept(T t,P1 p1,P2 p2,P3 p3,P4 p4); } @FunctionalInterface public interface Consumer5<T, P1, P2, P3, P4, P5>{ /** * 接收参数方法 * @param t 对象 * @param p1 参数一 * @param p2 参数二 * @param p3 参数三 * @param p4 参数四 * @param p5 参数五 */ void accept(T t,P1 p1,P2 p2,P3 p3,P4 p4,P5 p5); } }
- Builder调用方法
- Head
import lombok.*; /** * @author Javacfox */ @Setter @Getter @NoArgsConstructor @AllArgsConstructor @ToString(callSuper = true) @EqualsAndHashCode(callSuper = false) public class Head { private String actionType; private String currentTime; }
- Request
import com.alibaba.fastjson.JSONObject; import com.infosec.ra.common.build.Builder; import lombok.*; /** * @author Javacfox */ @Setter @Getter @NoArgsConstructor @AllArgsConstructor @ToString(callSuper = true) @EqualsAndHashCode(callSuper = false) public class Request { private Head header; private JSONObject body; public void setHeader(String actiontype,String currenttime){ this.header = Builder.of(Head::new) .with(Head::setActiontype,actiontype) .with(Head::setCurrenttime,currenttime) .build(); } }
- RequestBody
import com.alibaba.fastjson.JSONObject; import com.infosec.ra.common.build.Builder; import com.infosec.ra.common.build.outer.Signature; import lombok.*; /** * @author Javacfox */ @Setter @Getter @NoArgsConstructor @AllArgsConstructor @ToString(callSuper = true) @EqualsAndHashCode(callSuper = false) public class RequestBody { private Request request; private Signature signature; public void setRequest(String actiontype, String currenttime, JSONObject jsonObject){ this.request = Builder.of(Request::new) .with(Request::setHeader,actiontype,currenttime) .with(Request::setBody,jsonObject) .build(); } public void setSignature(String alg,String pubkey,String sign){ this.signature = Builder.of(Signature::new) .with(Signature::setAlg,alg) .with(Signature::setPubkey,pubkey) .with(Signature::setSign,sign) .build(); } }
- 调用示例
public static void main(String[] args) { JSONObject jsonObject = new JSONObject(); jsonObject.put("uuid","1312321"); jsonObject.put("devicetype","01"); jsonObject.put("pubkey","dadadasdas"); jsonObject.put("brand",""); jsonObject.put("address",""); jsonObject.put("email",""); jsonObject.put("telephone","1312213"); RequestBody requestBody = Builder.of(RequestBody::new) .with(RequestBody::setRequest, "", "", jsonObject) .with(RequestBody::setSignature, "sm3WithSm2", "asdsadas", "adssadas") .build(); System.out.println(JSON.toJSONString(requestBody,SerializerFeature.SortField)); }
- 结果打印
{ "request":{ "body":{ "address":"", "telephone":"1312213", "uuid":"1312321", "brand":"", "devicetype":"01", "email":"", "pubkey":"dadadasdas" }, "header":{ "actiontype":"", "currenttime":"" } }, "signature":{ "alg":"sm3WithSm2", "pubkey":"asdsadas", "sign":"adssadas" } }
3.Builder代码简单讲解
- 通过Supplier懒加载的特性保存需要创建的对象
- 将每一步的操作保存到Consumer中,存入到List集合
- 在build方法中通过Supplier的get()方法获取实例,在遍历list调用每个Consumer的accept方法给该实例的参数进行初始化