meta库的process包下的DiffProcessor

251 阅读5分钟
DiffType 枚举类中的抽象方法实现,需要枚举类中的每个对象都对其进行实现
public enum DiffType {
   NONE,ADDED,REMOVED,MODIFIED;

   public static boolean isModified(DiffType type){
       return  type!=null && type !=NONE;
   }
   
    public boolean isAdded() {
        return this == ADDED;
    }
    
   public boolean isRemoved() {
        return this == REMOVED;
    }
    
    public boolean isNone() {
        return this == NONE;
    }
}

静态变量可以用于引用所有对象的公共属性(对于每个对象不是唯一的)。

如果等于定义的元素,返回true

FieldDiff类

@Data
@Builder
public class FieldDiff {

  private String fieldName;

  private DiffType diffType;

  private Object original;

  private Object current;

  @Builder.Default
  private List<FieldDiff>  fields = new ArrayList<>();
}

Default字段表示注解的字段必须要有初始化表达式,如果在构造期间未明确设置,则该表达式会被默认使用,创建一个ArrayList类型,创建一个属于FieldDiff类型的字段

originalRemovedField类

default List<FieldDiff> originalRemovedField(Map<String,T> originalMapById,
                                             Map<String,T> currentMapById){
      return originalMapById.entrySet()
              .stream()
              .filter(entry-> !currentMapById.containsKey(entry.getKey()))
              .map(entry-> FieldDiff.builder()
                      .fieldName(entry.getKey())
                      .original(entry.getValue())
                      .diffType(DiffType.REMOVED)
                      .build())
              .collect(Collectors.toList());
}

方法名称:初始化删除字段(它的类型为字段差异)-
T - Type(Java 类)

  1. keySet返回此map中包含map的 Set 视图。 set由map支持,因此对map的更改会反映在set中,反之亦然。

  2. 返回此集合中元素的顺序流

  3. 返回由与给定谓词匹配的此流的元素组成的流。返回the new stream

  4. 如果currentMapById不包含此条目对应的键,返回false

  5. 返回由将给定函数应用于此流的元素的结果组成的流。返回符合FieldDiff类型的元素

  6. Map.entrySet返回map的元素视图.得到entry的键作为字段名,entry的值作为初始值,找到符合差异类型中的remove进行构造

  7. 使用collect将构造好的元素按照遇到的顺序累积到list列表中

 default Map<String, T> toMap(List<T> content, Function<T, String> idMapping) {
    return content
            .stream()
            .collect(Collectors.toMap(idMapping, Function.identity(), (a, b) -> {
                log.warn("Duplicate key, origin = {}, current = {}", a, b);
                return a;
       }));
}
  1. 默认方法就是接口可以有实现方法,而且不需要实现类去实现其方法。

  2. 返回此集合元素的顺序流

  3. Function接收参数并且返回结果的函数,T表示函数输入的类型,R表示函数结果的类型,identity方法表示始终返回其输入参数的函数

  4. ->表示一个函数式接口,表示对两个相同操作数的操作,产生与操作数相同类型的结果

  5. apply方法 将此函数应用于给定的参数

  6. 参数a和b在WARN级别中记录消息,复制键,起始值为空,当前值也为空

currentAddedField类

default List<FieldDiff> currentAddedField(Map<String, T> originalMapById,
                                          Map<String, T> currentMapById) {
    return currentMapById.entrySet()
            .stream()
            .filter(entry -> !originalMapById.containsKey(entry.getKey()))
            .map(entry -> FieldDiff.builder()
                    .fieldName(entry.getKey())
                    .current(entry.getValue())
                    .diffType(DiffType.ADDED)
                    .build())
            .collect(Collectors.toList());
}
  1. 默认方法就是接口可以有实现方法,而且不需要实现类去实现其方法。
  2. entrySet 返回此映射中包含的集合视图
  3. 返回此集合元素的顺序流
  4. 返回由与给定谓词匹配的此流的元素组成的流。返回the new stream ,判断originalMapById中是否包含与此条目对应的键
  5. R 新流的元素类型,map方法表示构造符合FieldDiff类型的元素的结果组成的流
  6. 找到与该条目对应的键作为字段名,与此条目对应的值作为当前值,判断它是不是枚举类DiffType下的ADDED方法,元素流构造完成
  7. 构造一个将输入元素累计到新列表中的收集器,使用collect方法将元素累计到这个list中

modifiedField类

default List<FieldDiff> modifiedField(Map<String,T> original,
                                        Map<String,T> current){
      ArrayList<FieldDiff> diff = new ArrayList<>();
      original.entrySet()
              .stream()
              .filter(entry-> current.containsKey(entry.getKey()))
              .forEach(entry->{
                  T originalValue = entry.getValue();
                  T currentValue = current.get(entry.getKey());
              if (!Objects.equals(originalValue,currentValue)){
         FieldDiff fieldDiff = FieldDiff.builder()
                          .fieldName(entry.getKey())
                          .original(originalValue)
                          .current(currentValue)
                          .diffType(DiffType.MODIFIED)
                          .build();
                  diff.add(fieldDiff);
              }
     });
return diff;
 }
  1. 创建一个diff对象,存储FieldDiff类型的元素
  2. -> 谓词的输入类型
  3. 找到起始值的mapping所包含的Set视图,返回此集合元素的顺序流,filter表示返回与current对应的键
  4. 对此流的每个元素执行操作
  5. 条目的值作为起始值,条目的键的值映射作为当前值,如果起始值和当前值不相等,找到它们的字段差异值,将它加入到数组diff中用来返回

diffTableField类

default FieldDiff diffTableField(List<T> original,
                                   List<T> current,
                                   String fieldName,
                                   Function<T, String> identity) {
      Map<String, T> originalMap = toMap(original, identity);
      Map<String, T> currentMap = toMap(current, identity);
      List<FieldDiff> columnFieldDiffs = new ArrayList<>(32);
      // removed
      List<FieldDiff> removedFields = originalRemovedField(originalMap, currentMap);
      columnFieldDiffs.addAll(removedFields);
      // added
      List<FieldDiff> addedFields = currentAddedField(originalMap, currentMap);
      columnFieldDiffs.addAll(addedFields);
      // modified
      List<FieldDiff> modifiedFields = modifiedField(originalMap, currentMap);
      columnFieldDiffs.addAll(modifiedFields);
      return FieldDiff.builder()
              .fieldName(fieldName)
              .diffType(columnFieldDiffs.isEmpty() ? DiffType.NONE : DiffType.MODIFIED)
              .fields(columnFieldDiffs)
              .build();
}
  1. 创建一个属于FieldDiff类型的方法,输入参数为起始值,当前值,字段名称,Function中的T表示输入类型的参数,String表示输出类型的参数,identify作为特征值
  2. 将特征值加入到original和current中作为初始值映射和当前值映射的集合,创建一个容量为32,类型为字段之间的差异所组成的列表,名称为列字段差异。
  3. 使用起始删除字段和当前已添加字段方法分别对originalMap和currentMap进行操作,起始删除字段方法是找到与originalMap和currentMap中的不同的键,当前已添加字段方法是找到与originalMap和currentMap中的不同的键,构造出字段差异的类型并且将其加入到list中返回 。列的field差异列表分别加入已删除的字段名和已添加的字段名。
  4. 找到修改过的originalMap和currentMap的差异值,加入到列的field差异列表中,检查列差异列表是否为空,如果不为空的话,它为已经修改的标志,如果为空,则为null,返回一开始输入的字段名称作为列之间字段差异类型的集合来返回。

Java 泛型 | 菜鸟教程 (runoob.com)