根据对象中的属性添加到列表

Posted

技术标签:

【中文标题】根据对象中的属性添加到列表【英文标题】:Add to a list based on property in an object 【发布时间】:2021-10-16 02:24:42 【问题描述】:
private static CodeList prepareChangeObject(CodeList codeList, CodeList existingCodeList, boolean dataExists)
            throws EntityValidationException 
        CodeList UpdatedCodeList = new CodeList();
        BeanUtils.copyProperties(codeList, UpdatedCodeList);
        Set<CodeListData> updatedDataList =UpdatedCodeList.getData().stream().collect(Collectors.toSet());
        updatedDataList.addAll(existingCodeList.getData());
        List<CodeListData> finalData = updatedDataList.stream().collect(
                collectingAndThen(toCollection(() -> new TreeSet<>(comparing(CodeListData::getKey))), ArrayList::new));
        finalData = finalData.stream().filter(data -> 
            if (data.getOperation() == null)
                data.setOperation(MetaConstants.OPERATION_ADD);
            if (null != data.getOperation()) 
                if (data.getOperation().equals(MetaConstants.OPERATION_DELETE) && dataExists)
                    exceptionMessagesList.add(
                            new ExceptionMessage("foundation.OperationNotAllowed", new String[]  data.getKey() ));
                if (data.getOperation().equals(MetaConstants.OPERATION_DELETE) && !dataExists)
                    return false;
                if (data.getOperation().equals(MetaConstants.OPERATION_ADD))
                    return true;
            
            return false;

        ).collect(Collectors.toList());
        UpdatedCodeList.setData(finalData);
        if(!CollectionUtils.isEmpty(exceptionMessagesList))
            throw new EntityValidationException(HTTPClientError.BAD_REQUEST, exceptionMessagesList);
        return UpdatedCodeList;
    

1.上述方法应根据指定的操作返回一个更改对象。

    public static void main(String[] args) throws JsonMappingException, JsonProcessingException, EntityValidationException 
    String jsonPost = "\n"
            + "  \"id\": \"temperature101\",\n"
            + "  \"descriptions\": [\n"
            + "    \n"
            + "      \"languageCode\": \"en\",\n"
            + "      \"description\": \"description\",\n"
            + "      \"longDescription\": \"long description\"\n"
            + "    ,\n"
            + "    \n"
            + "      \"languageCode\": \"de\",\n"
            + "      \"description\": \"description\",\n"
            + "      \"longDescription\": \"long description\"\n"
            + "    \n"
            + "  ],\n"
            + "  \"dataType\": \"String\",\n"
            + "  \"data\": [\n"
            + "    \n"
            + "      \"key\": \"val1\",\n"
            + "      \"value\": \"High\"\n"
            + "    ,\n"
            + "    \n"
            + "      \"key\": \"val4\",\n"
            + "      \"value\": \"Medium\"\n"
            + "    ,\n"
            + "    \n"
            + "      \"key\": \"val3\",\n"
            + "      \"value\": \"Low\"\n"
            + "    \n"
            + "  ]\n"
            + "";
    String jsonPatch = "\n"
            + "  \"id\": \"temperature101\",\n"
            + "  \"descriptions\": [\n"
            + "    \n"
            + "      \"languageCode\": \"en\",\n"
            + "      \"description\": \"description1\",\n"
            + "      \"longDescription\": \"long description1\"\n"
            + "    ,\n"
            + "    \n"
            + "      \"languageCode\": \"de\",\n"
            + "      \"description\": \"description1\",\n"
            + "      \"longDescription\": \"long description1\"\n"
            + "    \n"
            + "  ],\n"
            + "  \"dataType\": \"String\",\n"
            + "  \"data\": [\n"
            + "    \n"
            + "      \"key\": \"val1\",\n"
            + "      \"value\": \"High\",\n"
            + "      \"operation\": \"DELETE\"\n"
            + "\n"
            + "    ,\n"
            + "    \n"
            + "      \"key\": \"val4\",\n"
            + "      \"value\": \"Medium\",\n"
            + "      \"operation\": \"DELETE\"\n"
            + "    \n"
            + "  ]\n"
            + "";
    ObjectMapper mapper = new ObjectMapper();
    CodeList ExistingodeList = mapper.readValue(jsonPost, CodeList.class);
    CodeList currentCodeList = mapper.readValue(jsonPatch, CodeList.class);
    CodeList upDatetedCodeList = prepareChangeObject(currentCodeList, ExistingodeList, false);
    Gson gson = new Gson();
    System.out.println(upDatetedCodeList.toString());
    System.out.println(gson.toJson(upDatetedCodeList));
    

    以上主要方法测试代码
@Data
public class CodeListData 
    
    @Column("ID")
    @JsonIgnore
    private String id;
    
    @Column("KEY")
    private String key;
    
    @Column("VALUE")
    private String value;
    
    @Column("ETAG")
    @JsonIgnore
    private String etag;
    
    @JsonIgnore
    @Column("VERSION")
    @Version
    private Long version;
    
    @Transient
    @JsonProperty(access = Access.WRITE_ONLY)
    private String operation;


    Pojo 供参考
@Data
public class CodeList implements Persistable<String>

    @NotNull
    @Id
    @Column("ID")
    private String id;
    
    @MappedCollection(idColumn = "ID", keyColumn = "ID_SEQ")
    private List<CodeListDescriptions> descriptions = new ArrayList<>();
    
    @Column("DATA_TYPE")
    private String dataType;
    
    @Column("LENGTH")
    private String length;
    
    @MappedCollection(idColumn = "ID", keyColumn = "ID_SEQ")
    private List<CodeListData> data = new ArrayList<CodeListData>();
    
    @JsonIgnore
    @Column("VERSION")
    private Long version;
    
    @Column("ETAG")
    @JsonIgnore
    private String etag;
    
    @Transient
    @JsonIgnore
    @Setter
    private boolean isInsert;

    @JsonIgnore
    public boolean isNew() 
        return isInsert;
    

4.codeList pojo

@Data
public class CodeListDescriptions

    @Column("ISO")
    public String languageCode;
    
    @Column("DESCRIPTION")
    public String description;
    
    @Column("LONG_DESCRIPTION")
    public String longDescription;
    
    @Column("ID")
    @JsonIgnore
    private String id;


5.final 所需的输出只有"val3" 才能存在。该方法应该基于操作DELETEADD 删除或添加。问题是 val4 仍然在输出中,因为在创建 finalData 时,它更愿意将 "val4" 保留在不包含任何操作的现有数据中。最终输出需要包含添加的值和未在有效负载中指定但存在于第一个中的值。

【问题讨论】:

【参考方案1】:

您从现有数据集和更新数据集创建Set&lt;CodeListData&gt;CodeListData 在所有字段上定义其 equalshashCode 方法。请注意,Lombok 会忽略 transient 字段,但这些字段与使用 @Transient 注释的字段不同。所以你在Set 中有两次val4 一次使用DELETE 操作,一次没有任何操作。有DELETE的会被过滤掉,没有操作的会默认为ADD,留在SET中。

注意:我认为将Set 类型的变量命名为任何以List 结尾的变量是很不幸的。

【讨论】:

【参考方案2】:

它更愿意将 val4 与不包含任何操作的现有数据隔离开来

您使用此代码默认为add 操作,因此无论是否有操作,您都明确设置一个

if (data.getOperation() == null)
  data.setOperation(MetaConstants.OPERATION_ADD);

然后你检查它像

if (null != data.getOperation())  // this is always true, because you use the default one line before
  ...
  if (data.getOperation().equals(MetaConstants.OPERATION_ADD))
    return true;


所以最后的结局

return false;

永远不会到达。

【讨论】:

“不要对枚举使用等号”那些似乎是 equals 是正确选择的字符串。 啊,你说得对,我想我在阅读时跳过了它,我只是根据我的处理方式假设它。已编辑

以上是关于根据对象中的属性添加到列表的主要内容,如果未能解决你的问题,请参考以下文章

如何将列表的子集添加到另一个列表中的对象的属性-最佳/最快的做法

根据属性对不同列表中的对象进行分类

根据数组中的对象属性生成带有头部的列表

将新属性添加到另一个数组中的现有对象数组

使用 LINQ 获取两个比较列表的结果并根据结果更改列表中的属性

我试图用列表中的对象填充列表视图,但只显示名称属性,同时允许用户在列表视图中多选项目