0

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=demo@camunda.org) - 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=demo@camunda.org), UserResponse(status=null, id=mary, firstName=Mary, lastName=Anne, email=mary@camunda.org)]

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": "demo@camunda.org",
        "groupId": [
            "accounting",
            "sales"
        ]
    },
    {
        "userId": "mary",
        "name": "Mary Anne",
        "type": [
            "candidate"
        ],
        "email": "mary@camunda.org",
        "groupId": [
            "accounting",
            "sales"
        ]
    }
]
Tanmay Naik
  • 586
  • 1
  • 4
  • 16
  • Attached your class defination of `UserCandidates` and `UserDto` ? And why you are calling so manny api ? – Eklavya Jun 07 '20 at 09:49
  • Does this answer help you https://stackoverflow.com/q/29670116/6695569 ? It shows how to remove duplicates of a List of objects. – Stephane L Jun 07 '20 at 11:31
  • Does this answer your question? [Remove duplicates from a list of objects based on property in Java 8](https://stackoverflow.com/questions/29670116/remove-duplicates-from-a-list-of-objects-based-on-property-in-java-8) – Stephane L Jun 07 '20 at 11:32
  • @Eklavya that's the requirement – Tanmay Naik Jun 07 '20 at 11:58

1 Answers1

1

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());
}
Hadi J
  • 16,989
  • 4
  • 36
  • 62
  • You have done iteration on the wrong list. See there are 2 API's.In if condition the data is duplicate so need to remove duplicate and merge the that duplicate type in array of that that id. Next for else condition the data is duplicate and need to merge groupId in the array of that id – Tanmay Naik Jun 07 '20 at 12:27
  • pls see now I have changed the question – Tanmay Naik Jun 07 '20 at 13:26
  • which parameter I should add in merge function. As in code you have given ``mergeFunction()`` and the example of ``mergeFunction(UserDto u1,UserDto u2)`` has 2 paramters – Tanmay Naik Jun 07 '20 at 17:39
  • `(u1, u2) -> mergeFunction(u1,u2)` – Hadi J Jun 07 '20 at 17:41
  • getting ``java.lang.UnsupportedOperationException`` (if we could connect somewhere where u can help me out) – Tanmay Naik Jun 07 '20 at 18:05
  • I see, replace all `Arrays.asList(result.getX())` with `new ArrrayList<>(Arrays.asList(result.getX()))` in `userDto` consructor. I just copied your code! and have not tested it. – Hadi J Jun 07 '20 at 18:08
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/215479/discussion-between-tanmay-naik-and-hadi-j). – Tanmay Naik Jun 07 '20 at 18:38