1
resposta

Retorno de lista de TopicosDto com base na lista de Topicos

Olá! Alguem poderia me ajudar a interpretar melhor este return? Alguma dica de leitura? Obrigado!

public static List<TopicoDto> converter(List<Topico> topicos) {
        return topicos.stream().map(TopicoDto::new).collect(Collectors.toList());
    }
1 resposta

Olá!

Como esse trecho de código está utilizando os novos recursos do Java 8, pode ficar um pouco confuso para quem não está acostumado, pois são baseados nos paradigmas de programação funcional.

Vamos então converter o código para o Java "tradicional":

public static List<TopicoDto> converter(List<Topico> topicos) {
    // precisamos da lista de dtos, inicialmente vazia
    List<TopicoDto> dtos = new ArrayList<>();

    // percorremos todos os topicos
    for(Topico topico : topicos) {
        // para cada Topico, precisamos criar um dto e passar o proprio topico para o construtor
        TopicoDto dto = new TopicoDto(topico);

        // adicionamos o dto na lista de dtos
        dtos.add(dto);
    }

    // retornamos a lista de dtos, que foi preenchida no loop for anterior
    return dtos;
}

Repare que no Java tradicional esse tipo de código, que precisa percorrer uma lista e transforma-la em outra lista, acaba ficando bastante verboso. No Java 8 podemos simplificar esse tipo de código.

Por exemplo, podemos fazer o loop for da seguinte maneira:

public static List<TopicoDto> converter(List<Topico> topicos) {
    List<TopicoDto> dtos = new ArrayList<>();

    topicos.stream().forEach(topico -> {
        TopicoDto dto = new TopicoDto(topico);
        dtos.add(dto);
    });

    return dtos;
}

Essa sintaxe(topico -> {}) que foi passada como argumento para o método forEach é chamada de Expressão Lambda.

Mas na verdade nosso objetivo é percorrer a lista para transformá-la em outra lista, ou seja, queremos mapear de um objeto para outro, e esse conceito é chamado de Map, tendo um outro método que faz isso:

public static List<TopicoDto> converter(List<Topico> topicos) {
    List<TopicoDto> dtos = new ArrayList<>();

    topicos.stream().map(topico -> {
        return new TopicoDto(topico);
    });

    return dtos;
}

No código anterior foi feito o mapeamento de Topico para TopicoDto, entretanto ainda precisamos adicionar todos os tópicos que foram mapeados para topicoDto em uma nova lista:

public static List<TopicoDto> converter(List<Topico> topicos) {
    List<TopicoDto> dtos = 
    topicos.stream().map(topico -> {
        return new TopicoDto(topico);
    }).collect(Collectors.toList());

    return dtos;
}

E agora podemos simplificar mais ainda o código, retornando a lista diretamente, sem precisar criar uma variavel:

public static List<TopicoDto> converter(List<Topico> topicos) {
    return topicos.stream().map(topico -> {
            return new TopicoDto(topico);
        }).collect(Collectors.toList());
}

E agora também é possível simplificar a expressão lambda, deixando ela menor ainda:

public static List<TopicoDto> converter(List<Topico> topicos) {
    return topicos.stream().map(TopicoDto::new).collect(Collectors.toList());
}

Agora o código ficou bem menor, em uma linha só. Porém fica difícil de entender sem os conhecimentos de Java 8.

Recomendo você fazer esse curso de Java 8 aqui na Alura, para entender melhor esses conceitos:

https://cursos.alura.com.br/course/java8-lambdas

Bons estudos!