端午安康--DTO,VO,POJO深拷贝工具

2,010 阅读3分钟

端午安康--DTO,VO,POJO深拷贝工具

不管是经典的MVC框架还算是现在火热的DDD领域驱动设计,为了业务之间的结构分离,都生成了各种对象,比如VO,DTO,POJO等十分常见,还有Domain,Value,Entity等领域对象也是频繁出现,随之而来的也是各个对象之间的转换,于是,各家拷贝工具也是百家齐放,争奇斗艳,我试着写了一个,斗胆发出来献献丑

功能

  • 同属性直接复制
  • 属性特异化赋值
  • 同名但是类型不同的属性(下一步方向)

结构

工具类主要的功能主要分为两个功能

  1. 相同属性之间的复制 使用Spring的BeanCopier进行复制,相对于其他复制工具类,BeanCopier的效率相对较高,且简单易用,不用再加入第三方Jar(如果你觉得Spring也是第三方,我没有意见)

  2. 其他属性的赋值,使用Java8新工具类BiConsumerBiConsumer可以对出口对象进特异化赋值,比如字典的Value换成Name,增加子集对象(典型的订单下的商品),还可以有其他特殊的操作会在例子中演示

源码

  • 单个对象
public static <S, T> T convertOne(Class<S> source, Class<T> target, S view, BiConsumer<S, T> consumer) {
        BeanCopier copier = BeanCopier.create(source, target, false);
        return copyOne(view, target, consumer, copier);
    }
  • 集合对象
public static <S, T> List<T> convertList(Class<S> source, Class<T> target, List<S> list, BiConsumer<S, T> consumer) {
        BeanCopier copier = BeanCopier.create(source, target, false);
        return list.stream()
                   .map(copyMapper(target, consumer, copier))
                   .filter(Objects::nonNull)
                   .collect(Collectors.toList());
    }
  • 可扩展
//Set
//Map
其实代码逻辑相当的简单,所以扩展也非常简单容易,如果有其他需求可以方便的进行任意的扩展
  • 私有方法
private static <S, T> Function<S, T> copyMapper(Class<T>target,BiConsumer<S, T> consumer, BeanCopier copier) {
        return source -> copyOne(source, target, consumer, copier);
    }

private static <S, T> T copyOne(S source, Class<T> target, BiConsumer<S,T> consumer, BeanCopier copier) {
        try {
            T t = target.newInstance();
            copier.copy(source, t, null);
            //todo consumer可以传空,即只做复制,不做特异化操作
            if (consumer != null) {
                consumer.accept(source, t);
            }
            return t;
        } catch (Exception e) {
            //todo 请自行处理异常逻辑,这边简单返回null
            return null;
        }
    }

例子

List<Order> orders = new ArrayList<>();
convertList(Order.class, OrderVo.class, orders, (s, t) -> {
    //设置其他属性
    t.setGoods(goods);
    //特殊属性转化
    t.setOrderTimeString(s.getOrderTime().toString());
});

结语

相对于其他的深拷贝工具,本工具的优点就是简单快捷,无第三方工具类,使用简单,而不是需要增加依赖,同时功能也相对强大,将特殊字段的处理逻辑交由外部传入,可以让调用方做到完全自主化的特异化赋值,最后,希望能够帮助到你

端午小礼物

整理这个工具类的时候,发现了一段其他代码,稍微看了下,是在Java8中,Stream流式处理集合功能相当强大,但是其中的distinct()却不提供针对对象属性字段进行去重的操作,不得不说略显可惜,遂有了这一小段代码,这段代码通过Streamfilter()方法进行对针对某一个属性的过滤,代码如下,聪明的你肯定知道咋用,最后的最后,祝端午安康,阖家幸福

public static <T> Predicate<T> distinctByKey(Function<T, String> keyExtractor) {
    Set<String> set = ConcurrentHashMap.newKeySet();
    return t -> set.add(keyExtractor.apply(t));
}