根据对象中的属性添加到列表
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"
才能存在。该方法应该基于操作DELETE
或ADD
删除或添加。问题是 val4 仍然在输出中,因为在创建 finalData 时,它更愿意将 "val4"
保留在不包含任何操作的现有数据中。最终输出需要包含添加的值和未在有效负载中指定但存在于第一个中的值。
【问题讨论】:
【参考方案1】:您从现有数据集和更新数据集创建Set<CodeListData>
。 CodeListData
在所有字段上定义其 equals
和 hashCode
方法。请注意,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
是正确选择的字符串。
啊,你说得对,我想我在阅读时跳过了它,我只是根据我的处理方式假设它。已编辑以上是关于根据对象中的属性添加到列表的主要内容,如果未能解决你的问题,请参考以下文章
如何将列表的子集添加到另一个列表中的对象的属性-最佳/最快的做法