Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

[Dúvida] List<> x Optional<>

Olá Bom dia, como vai? pergunta a). Levando em consideração a classe Principal.class e a interface ArtistaRepository - códigos abaixo, por que não consigo utilizar um forEach no lambda no método buscarMusicasPorArtista(), igual foi feito no método listarMusicas()? seria porque estou utilizando um um List<> e não um Optional<> lá na interface ArtistaRepository? Por favor poderia me ajudar? Forte Abraço :)

public interface ArtistaRepository extends JpaRepository<Artistas, Long> { // utilizando Derived Queries, Optional findByNomeContainingIgnoreCase(String musica);

//utilizando o JPQL - Java Persistence Query Language
// O m irá representar as músicas. Logo, SELECT m FROM Artista a.
// Lembre-se de diferenciar as músicas com m e o artista com a ao longo da query, ambos em minúsculas.
//
// Precisamos acrescentar um JOIN para que, na tabela de artista, onde o nome for o especificado,
// ele retorne as músicas associadas a ele. Portanto, vamos implementar JOIN a.musicas e o alias m onde a.nome
// é semelhante ao nome especificado, usando o ILIKE.
//
// Assim, se solicitamos "Busque as músicas do artista Taylor", o sistema precisa trazer somente as músicas de Taylor.
// Portanto, temos que adicionar o símbolo de porcentagem e o nome do nosso parâmetro, que será nome
@Query("SELECT m FROM Artistas a JOIN a.musicas m where a.nome ILIKE %:nome%")
List<Musicas> buscaMusicasPorArtista(String nome);

}

private void buscarMusicasPorArtista() {
    System.out.println("-> Informe o nome da Música para Buscar seu Artist: ");
    var nome = leitura.nextLine();
    List<Musicas> listaMusicas = repositorio.buscaMusicasPorArtista(nome);
    listaMusicas.forEach(System.out::print);
}

private void listarMusicas() {
    System.out.println("--- Listando os Artistas Cadastrados ---");
    List<Artistas> artistas = repositorio.findAll();
    // artistas.forEach(System.out::println);
    // artistas.forEach(System.out::println);

    // pode-se imprimir:
    // para cda artista, me passa as músicas.
    artistas.forEach(a -> a.getMusicas().forEach(System.out::print));
}
2 respostas
solução!

Olá Maurício, bom dia! Espero que esteja bem.

No seu método buscarMusicasPorArtista(), você está utilizando uma List<Musicas> retornada pelo método buscaMusicasPorArtista(String nome), que é uma consulta JPQL retornando uma lista de músicas. Quando você utiliza List<Musicas>, você pode aplicar o forEach diretamente, como fez: listaMusicas.forEach(System.out::print);.

O Optional<> é utilizado em situações onde pode haver ou não um valor presente. Ele é comumente usado para evitar null e ajudar a lidar com situações onde um valor pode não estar presente. No caso do seu método findByNomeContainingIgnoreCase(String musica), ele retorna um Optional<Artistas>, o que significa que pode ou não haver um artista com o nome especificado.

A diferença crucial aqui é que Optional não é uma coleção e, portanto, não suporta forEach diretamente. Ele é mais usado para verificar a presença de um valor e, em caso afirmativo, realizar alguma ação com ele, por exemplo, usando ifPresent().

Portanto, no seu caso, como você está lidando com uma List<Musicas>, o uso de forEach é totalmente adequado e esperado. O Optional não é necessário para a operação que você está realizando, que é iterar sobre uma lista de músicas.

Espero ter ajudado e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.

Bom dia, estou muito bem e espero que esteja bem também! Prezado @Armando Barros, muito obrigado pelas informações / respostas. Foram de um aprendizado enorme.

Agradeço por reponder todas as minhas dúvidas, respostas claras e certeiras! Extraordinário!

Muito Obrigado, Deus Abençoe Maurício G