Search code examples
javalistjava-stream

How to use stream to get an object from a list of lists


My object is a collection of profiles that inside has a set of PerfilMenunode

public class Perfil {
    [...]
    @OneToMany(cascade = CascadeType.ALL)
    @JoinColumn(name = "ID_PERFIL")
    @LazyCollection(LazyCollectionOption.FALSE)
    private List<PerfilMenunode> perfilMenunodes;

What I want to do is this function but only using stream

public PerfilMenunode darPerfilMenuNode(List<Perfil> perfiles) {
    PerfilMenunode perfilMenunode = null;
    for (Perfil perfil : perfiles) {
        perfilMenunode = perfil.getPerfilMenunodes().stream().filter(pm -> pm.getMenunode().getNombreCorto().equals(Constante.MENU_ADMINPERFIL_NOMBRECORTO)).findFirst().orElse(null);
        if(perfilMenunode!=null) {
            return perfilMenunode;
        }
    }
    return perfilMenunode;
}

Any solution?


Solution

  • It would give the following using flatMap

    public PerfilMenunode darPerfilMenuNode(List<Perfil> perfiles) {
        return perfiles.stream()
                .map(Perfil::getPerfilMenunodes)
                .flatMap(Collection::stream)
                .filter(pm -> pm.getMenunode()
                                .getNombreCorto()
                                .equals(Constante.MENU_ADMINPERFIL_NOMBRECORTO)
                )
                .findFirst()
                .orElse(null);
    }
    

    But if you're using , you can use Stream#mapMulti instead of flatMap, it gives better performance, even more if your perfilMenunodes are small collections or empty collections

    public PerfilMenunode darPerfilMenuNode(List<Perfil> perfiles) {
        return perfiles.stream()
                .mapMulti((Perfil perfil, Consumer<PerfilMenunode> consumer) -> {
                    perfil.getPerfilMenunodes().forEach(consumer::accept);
                })
                .filter(pm -> pm.getMenunode()
                                .getNombreCorto()
                                .equals(Constante.MENU_ADMINPERFIL_NOMBRECORTO)
                )
                .findFirst()
                .orElse(null);
    }