Tanmay Naik
Tanmay Naik

Reputation: 658

Remove duplicate from object and merge in array

Code sample:-

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;
    }

So in if condition the response from API I'm getting is

UserRefer(id=demo, firstName=Demo, lastName=Demo, [email protected]) - userResponse object

And from listResponse object data is [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 condition the response for listGroup is [UserResponse(status=null, id=demo, firstName=Demo, lastName=Demo, [email protected]), UserResponse(status=null, id=mary, firstName=Mary, lastName=Anne, [email protected])]

So now you can see the data is duplicate. The output i want is for when userId is not empty from the data it should take type and merge the array

else if grouped not empty the data it should take for groupType and merge in the array removing duplicte and merging in same object

Output :-

[
    {
        "userId": "demo",
        "name": "Demo Demo",
        "type": [
            "candidate",
            "assignee"
        ],
        "email": "[email protected]",
        "groupId": [
            "accounting",
            "sales"
        ]
    },
    {
        "userId": "mary",
        "name": "Mary Anne",
        "type": [
            "candidate"
        ],
        "email": "[email protected]",
        "groupId": [
            "accounting",
            "sales"
        ]
    }
]

Upvotes: 0

Views: 521

Answers (1)

Hadi
Hadi

Reputation: 17299

You need some fundamental changes in your code.

1- instead of using ResponseEntity<String> use ResponseEntity<UserCandidates[]> response by this changing you don't need use Gson() dependency.

2- You don't need to use StringUtils to check to be empty. there is same method for both string and list objects.

3- For the duplicate date I define a Map<String,UserDto> with id as key and userDto object as a value. and where the userDto data is created I store it in the map with the id. as you see for storing userDto object in the map I used merge method that for the duplicate key(id) it has a merge function.

Tip: for readability would be nice to separate the restTemplate call in other class may you reuse it too.

mergeFunction is somthing like this:

private UserDto mergeFunction(UserDto u1,UserDto u2){
    u1.getType().addAll(u2.getType());
    u1.getGroupId().addAll(u2.getGroupId());
    return u1;
 }  

and complete code is:

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());
}

Upvotes: 1

Related Questions