java - 从对象中删除重复项并合并到数组中
问题描述
代码示例:-
public List<UserDto> getUserCandidates(String taskId) {
List<UserCandidates> listResponse;
ResponseEntity<String> response=restTemplate.getForEntity(configProperties.getUrl()+"/task/"+taskId+"/identity-links",
String.class);
listResponse =new Gson().fromJson(response.getBody(), new TypeToken<ArrayList<UserCandidates>>(){}.getType());
listResponse.forEach(result->{
if(!StringUtils.isEmpty(result.getUserId())){
ResponseEntity<UserRefer> userResponse=restTemplate.getForEntity(configProperties.getUrl()+"/user/"+result.getUserId()+"/profile", UserRefer.class);
userDtoList.add(new UserDto(result.getUserId(), Arrays.asList(result.getGroupId()), Arrays.asList(result.getType()), userResponse.getBody().getFirstName(),
userResponse.getBody().getLastName(), userResponse.getBody().getEmail()));
}
else if(!StringUtils.isEmpty(result.getGroupId())) {
ResponseEntity<String> responseGroup=restTemplate.getForEntity(configProperties.getUrl()+"/user"+"?memberOfGroup="+result.getGroupId(), String.class);
List<UserResponse> listGroup=new Gson().fromJson(responseGroup.getBody(), new TypeToken<ArrayList<UserResponse>>(){}.getType());
listGroup.forEach(resultGroup->{
userDtoList.add(new UserDto(resultGroup.getId(),Arrays.asList(result.getGroupId()),
Arrays.asList(result.getType()),resultGroup.getFirstName(),resultGroup.getLastName(),resultGroup.getEmail()));
});
}
});
return userDtoList;
}
因此,如果条件我得到的来自 API 的响应是
UserRefer(id=demo, firstName=Demo, lastName=Demo, email=demo@camunda.org) - userResponse object
而从 listResponse 对象数据是[UserCandidates(userId=null, groupId=accounting, type=candidate), UserCandidates(userId=null, groupId=sales, type=candidate), UserCandidates(userId=demo, groupId=null, type=assignee)]
next in else if 条件 listGroup 的响应是[UserResponse(status=null, id=demo, firstName=Demo, lastName=Demo, email=demo@camunda.org), UserResponse(status=null, id=mary, firstName=Mary, lastName=Anne, email=mary@camunda.org)]
所以现在你可以看到数据是重复的。我想要的输出是当 userId 从它应该获取的数据中不为空type
并合并数组时
否则,如果分组不清空它应该获取的数据groupType
并合并到数组中,删除重复项并合并到同一个对象中
输出 :-
[
{
"userId": "demo",
"name": "Demo Demo",
"type": [
"candidate",
"assignee"
],
"email": "demo@camunda.org",
"groupId": [
"accounting",
"sales"
]
},
{
"userId": "mary",
"name": "Mary Anne",
"type": [
"candidate"
],
"email": "mary@camunda.org",
"groupId": [
"accounting",
"sales"
]
}
]
解决方案
您需要对代码进行一些根本性的更改。
1-而不是ResponseEntity<String>
使用ResponseEntity<UserCandidates[]> response
这种改变使用你不需要使用Gson()
依赖。
2-您不需要使用StringUtils
检查为空。字符串和列表对象都有相同的方法。
3- 对于重复的日期,我定义了一个Map<String,UserDto>
id 作为键,userDto
对象作为值。在userDto
创建数据的位置,我将其存储在带有 id 的地图中。userDto
正如您在映射中存储对象时看到的,我使用merge
了对于重复键(id)它具有合并功能的方法。
提示:为了可读性,将其他类中的调用分开会很好,restTemplate
您也可以重用它。
mergeFunction 是这样的:
private UserDto mergeFunction(UserDto u1,UserDto u2){
u1.getType().addAll(u2.getType());
u1.getGroupId().addAll(u2.getGroupId());
return u1;
}
完整的代码是:
public List<UserDto> getUserCandidates(String taskId) {
Map<String, UserDto> userDtoMap = new HashMap<>();
Map<String, String> params = new HashMap<>();
ResponseEntity<UserCandidates[]> response = restTemplate
.getForEntity(configProperties.getUrl() + "/task/" + taskId + "/identity-links",
UserCandidates[].class, params);
Arrays.asList(response.getBody()).forEach(result -> {
if (!result.getUserId().isEmpty()) {
ResponseEntity<UserRefer> userResponse = restTemplate
.getForEntity(configProperties.getUrl() + "/**", UserRefer.class);
userDtoMap.merge(result.getUserId(), new UserDto(result.getUserId(),
new ArrayList<>(Arrays.asList(result.getGroupId())), Arrays.asList(result.getType()),
userResponse.getBody().getFirstName(),
userResponse.getBody().getLastName(),
userResponse.getBody().getEmail()), (u1, u2) -> mergeFunction(u1,u2));
} else if (!result.getGroupId().isEmpty()) {
String requestUri = configProperties.getUrl() + "/user" +
"?memberOfGroup={memberOfGroup}";
Map<String, String> userResParam = new HashMap<>();
userResParam.put("memberOfGroup", result.getGroupId());
ResponseEntity<UserResponse[]> responseGroup = restTemplate
.getForEntity(requestUri, UserResponse[].class, userResParam);
Arrays.asList(responseGroup.getBody()).forEach(resultGroup -> {
userDtoMap.merge(resultGroup.getId(), new UserDto(resultGroup.getId(),
Arrays.asList(result.getGroupId()),
Arrays.asList(result.getType()), resultGroup.getFirstName(),
resultGroup.getLastName(),
resultGroup.getEmail()), (u1, u2) -> mergeFunction(u1,u2));
});
}
});
return new ArrayList<>(userDtoMap.values());
}
推荐阅读
- symfony - Symfony 4,为多对多关系上下文中的 findby 自定义方法提供简单示例
- ruby-on-rails - Rspec 组测试输出
- node.js - 如何以 zipkin ui 支持的格式(json)将 zipkin 跟踪写入文件?
- ansible - 脚本中的 Ansible 变量
- docker - 无法在 docker 容器内执行操作
- ios - 当包含 UIViewController viewWillDisappear 被调用时,子视图 UIView 会得到任何回调吗
- ios - 在 Vimeo 上上传视频时出现问题(通过我的 iOS 应用程序)
- node.js - Angular 正在使用 socket.io 创建许多套接字
- javascript - Chart.js 传递一个以 1 而不是 0 开头的数组的问题
- java - scala - 将字符串转换为数字的受限方式