2

I have these three dto classes :

public class OrganismeDTO {
    private Long organismeId;
    private String libelle;
    private List<RoleDTO> rolesDTO;
}

public class RoleDTO {
    private String lib;
    private Long roleId;
    private List<ProfilDTO> profilsDTO;
}

public class UtilisateurRoleDto {
    private String organismeLib;
    private String roleLib;
}

And in my DAO I have a function that will return a list of UtilisateurRoleDto.

What I want, is to create a list of OrganismeDTOfrom UtilisateurRoleDto list (Which I can get from my DAO), so for example, if I have a list of UtilisateurRoleDto as following:

"Organisme 1", "Role 1"
"Organisme 1", "Role 2"
"Organisme 2", "Role 1"
"Organisme 2", "Role 3"
"Organisme 3", "Role 3"

I want a list of OrganismeDTO in result as following (where each OrganismeDTO has a list of RoleDTO) :

"Organisme 1" : ["Role 1", "Role 2"]
"Organisme 2" : ["Role 1", "Role 3"]
"Organisme 3" : ["Role 3"]

How can I implement this using Java 8 streams?

Update:

When I construct the RoleDTO I need to inject RoleDTO.profilsDTO by a list I get from a function that takes OrganismeDTO.roleId and returns List<ProfilDTO>.

5
  • How are RoleDTO and roleLib similar? Commented Oct 3, 2017 at 11:09
  • baeldung.com/java-groupingby-collector Commented Oct 3, 2017 at 11:14
  • I think if you create a map from UtilisateurRoleDto list then will help you to find the solution. Commented Oct 3, 2017 at 11:52
  • @nullpointer I didnt understand your question, in fact, RoleDTO.lib is the same as UtilisateurRoleDto.roleLib Commented Oct 3, 2017 at 13:21
  • @VishnuKR that works for me Commented Oct 3, 2017 at 13:49

2 Answers 2

1

You can do it with a custom collect(I added getters and some obvious constructors):

Map<String, OrganismeDTO> map = dt.stream().collect(HashMap::new, (m, t) -> {
    m.computeIfAbsent(t.getOrganismeLib(), x -> new OrganismeDTO(t.getOrganismeLib())).getRolesDTO().add(new RoleDTO(t.getRoleLib()));
}, (m1, m2) -> {
    m2.forEach((k,v) -> {
        OrganismeDTO organismeDTO = m1.get(k);
        if (organismeDTO != null ) {
            organismeDTO.getRolesDTO().addAll(v.getRolesDTO());
        } else {
            m1.put(k, v);
        }
    });
});

And then all that's left if to create List from the values.

List<OrganismeDTO> list = map.values().stream().collect(Collectors.toList());
Sign up to request clarification or add additional context in comments.

4 Comments

When I tried this I got a NullPointerException in this line : .add(new RoleDTO(t.getRoleLib()), is it because getRolesDTO() is not initialized as an ArrayList ?
@AimadMAJDOU Yes, in my "obvious constructor" I initialize it with an ArrayList.
What I mean is the getRolesDTO() will be null since it has to be initialized as a new ArrayList, so what I did is: private List<RoleDTO> rolesDTO = new ArrayList<>(); in the OrganismeDTO class and the error is gone.
This solution is working for me, thanks for your help, it would be great if you could explain the code you wrote.
1

The only way I can think of at the moment is this:

Map<String, List<String>> collect = list.stream()
            .collect(Collectors.groupingBy(UtilisateurRoleDto::getOrganismeLib,
                    Collectors.mapping(UtilisateurRoleDto::getRoleLib, Collectors.toList())));

List<OrganismeDTO> result = collect.entrySet().stream()
        .map(entry -> new OrganismeDTO(entry.getKey(),
                entry.getValue().stream()
                        .map(RoleDTO::new)
                        .collect(toList())))
        .collect(Collectors.toList());

Firstly you can group your UtilisateurRoleDto by it's organismeLib field. After that you process the obtained result and map it to your wanted entities.

3 Comments

Thank you, but I forgot to add the id field for OrganismeDTO and RoleDTO, could you please recheck my update.
From where should I get those ids ? or do I have to generate them randomly ? ...
They are already defined : OrganismeDTO.organismeId and RoleDTO.roleId

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.