Transforming Collections into Stream

1

Would there be a way to convert the following code to java 8 Stream?

    setores = new SetorBusiness().buscarEtiquetaFuncionario(null, codDiretoriaSelecionada, codCoordSelecionada, uf, cidade, servidor, null, null, agencia);
    parametrosRelatorio = new ParametrosRelatorio("QtdUorgFunc", SaidaRelatorioEnum.buscaEnum(tipo));
    parametrosRelatorio.getParams().put("sub", FacesContext.getCurrentInstance().getExternalContext().getRealPath("/relatorios/SubQtdUorgFunc"));
    if (!setores.isEmpty()) {
    List<Setor> listaSetores = new ArrayList<Setor>();
    Setor set;
    Map<String, List<Setor>> lista = new LinkedHashMap<String, List<Setor>>();

    for (Setor s : setores) {
        if (lista.containsKey(s.getSiglaSetor())) {
            lista.get(s.getSiglaSetor()).add(s);

        } else {
            List<Setor> se = new ArrayList<Setor>();
            se.add(s);
            lista.put(s.getSiglaSetor(), se);

        }
    }

    for (List<Setor> l : lista.values()) {
        set = new Setor();
        set.setSiglaSetor(l.get(0).getSiglaSetor());
        set.setCodigo(l.get(0).getCodigo());

        set.getSetorImpressaoPDF().addAll(l);
        listaSetores.add(set);
    }

   Util.gerarRelatorio(listaSetores, parametrosRelatorio);
    
asked by anonymous 13.11.2017 / 18:23

1 answer

0

This should resolve this:

Map<String, List<Setor>> map = setores
        .stream()
        .collect(Collectors.groupingBy(Setor::getSiglaSetor));

List<Setor> listaSetores = map.values().stream().map(lista -> {
    Setor set = new Setor();
    set.setSiglaSetor(lista.get(0).getSiglaSetor());
    set.setCodigo(lista.get(0).getCodigo());
    set.getSetorImpressaoPDF().addAll(lista);
    return set;
}).collect(Collectors.toList());

Or, you can use this equivalent if you want to be a little shorter:

List<Setor> listaSetores = setores
        .stream()
        .collect(Collectors.groupingBy(Setor::getSiglaSetor))
        .values()
        .stream()
        .map(lista -> {
            Setor set = new Setor();
            set.setSiglaSetor(lista.get(0).getSiglaSetor());
            set.setCodigo(lista.get(0).getCodigo());
            set.getSetorImpressaoPDF().addAll(lista);
            return set;
        }).collect(Collectors.toList());

In the meantime:

  • What you want to put together is a list of industry groups, not a list of industries. The Setor class should have only one responsibility, which is to describe what a sector is in its domain of application. However, its Setor class has a second responsibility, which is to group sectors of the same code for PDF printing. Therefore, it is best to have a Grupo class so that each class has only one responsibility.

  • The name of the getSiglaSetor() method is redundant because since it is in the Setor class, the suffix Setor in the name is unnecessary and getSigla() would be enough.

So, with this new class, I think this would be better:

public class Grupo {
    private final String sigla;
    private final String codigo;
    private final List<Setor> setores;

    public Grupo(List<Setor> setores) {
         this.sigla = setores.get(0).getSigla();
         this.codigo = setores.get(0).getCodigo();
         this.setores = setores;
    }

    public String getSigla() {
        return sigla;
    }

    public String getCodigo() {
        return codigo;
    }

    public List<Setor> getSetorImpressaoPDF() {
        return setores;
    }
}

The code with stream would look like this:

List<Grupo> listaGrupos = setores
        .stream()
        .collect(Collectors.groupingBy(Setor::getSigla))
        .values()
        .stream()
        .map(Grupo::new)
        .collect(Collectors.toList());

If you want to keep the original order, you can change this:

        .collect(Collectors.groupingBy(Setor::getSigla))

So:

        .collect(Collectors.groupingBy(
            Setor::getSigla,
            LinkedHashMap::new,
            Collectors.toList()
        ))
    
13.11.2017 / 19:17