Quanto tento executa o código, da uma SQLException: After end of result set.
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import br.com.alura.jdbc.modelo.Categoria;
import br.com.alura.jdbc.modelo.ConnectionFactory;
import br.com.alura.jdbc.modelo.Produto;
import dao.CategoriaDAO;
import dao.ProdutoDAO;
public class TestaListagemDeCategorias {
    public static void main(String[] args) throws SQLException {
        try (Connection connection = new ConnectionFactory().recuperarConexao()) {
            CategoriaDAO categoriaDAO = new CategoriaDAO(connection);
            List<Categoria> listaDeCategoria = categoriaDAO.listarComProdutos();
            listaDeCategoria.stream().forEach(ct -> {
                System.out.println(ct.getNome());
                    for(Produto produto: ct.getProdutos()) {
                        System.out.println(ct.getNome() + " - " + produto.getNome());
                    }
            });
        }
    }
}package dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import br.com.alura.jdbc.modelo.Categoria;
import br.com.alura.jdbc.modelo.Produto;
public class CategoriaDAO {
    private Connection connection;
    public CategoriaDAO(Connection connection) {
        this.connection = connection;
    }
    public List<Categoria> listar() throws SQLException {
        List<Categoria> categorias = new ArrayList<>();
        String sql = "SELECT ID, NOME FROM CATEGORIA";
        try (PreparedStatement pstm = connection.prepareStatement(sql)) {
            pstm.execute();
            try (ResultSet rst = pstm.getResultSet()) {
                while (rst.next()) {
                    Categoria categoria = new Categoria(rst.getInt(1), rst.getString(2));
                    categorias.add(categoria);
                }
            }
        }
        return categorias;
    }
    public List<Categoria> listarComProdutos() throws SQLException {
        Categoria ultima = null;
        List<Categoria> categorias = new ArrayList<>();
        String sql = "SELECT C.ID, C.NOME, P.ID, P.DESCRICAO FROM CATEGORIA C INNER JOIN" + " PRODUTO P ON C.ID = P.CATEGORIA_ID";
        try (PreparedStatement pstm = connection.prepareStatement(sql)) {
            pstm.execute();
            try (ResultSet rst = pstm.getResultSet()) {
                if (ultima == null || !ultima.getNome().equals(rst.getString(2))) {
                    while (rst.next()) {
                        Categoria categoria = new Categoria(rst.getInt(1), rst.getString(2));
                        ultima = categoria;
                        categorias.add(categoria);
                    }
                    Produto produto = new Produto(rst.getInt(3), rst.getString(4), rst.getString(5));
                    ultima.adicionar(produto);
                }
            }
        }
        return categorias;
    }
}Outra dúvida minha é sobre a linha "SELECT C.ID, C.NOME, P.ID, P.DESCRICAO FROM CATEGORIA C INNER JOIN" + " PRODUTO P ON C.ID = P.CATEGORIA_ID", não sei o que isso deveria fazer exatamente. O requisito para este curso JDBC era o curso Introdução ao SQL com MySQL: manipule e consulte dados, mas nesse curso de introdução não foi introduzido algum comando SQL desse tipo.
 
            