collections-java-api-2023 icon indicating copy to clipboard operation
collections-java-api-2023 copied to clipboard

Map Ordenação LivrariaOnline - exibirLivrosOrdenadosPorPreco(),

Open Udinei opened this issue 2 years ago • 3 comments

Boa tarde! Camila!

Fazendo os exercicios de Map e nalisando o retorno do metodo exibirLivrosOrdenadosPorPreco(), me parece que esse metodo não esta ordenando corretamente, mesmo usando o Comparable<Livro>, ou Comparator<Livro> que também da o mesmo resultado?.

Baixei suas classes e deu o mesmo resultado, pra mim o retorno não esta correto!

Dei um pesquisada e vi alguns exemplos para fazer essa ordenação, mas achei muito complexos! Pode verficar por favor e dar um retorno?

Vou continuar pesquisando aqui uma forma mais simples de fazer isso!

Obrigado!!

Udinei avatar Sep 03 '23 16:09 Udinei

Bom dia Camila!

Consegui fazer! Esse foi o exemplo mais simples que consegui implementar, os outros ficaram muito complexos!

public void exibirLivrosOrdenadosPorPreco() {
TreeMap<Double, Livro> livrosOrdenados = new TreeMap<>(new Comparator() {

     @Override
        public int compare(Double preco1, Double preco2) {
            return Double.compare(preco1, preco2);
        }
    });

    System.out.println(livrosOrdenados.entrySet());
    for (var entry : livrosMap.entrySet()) {
        Livro livro = entry.getValue();
        double preco = livro.getPreco();
        livrosOrdenados.put(preco, entry.getValue());
    }

    System.out.println(livrosOrdenados);

}`

Udinei avatar Sep 08 '23 14:09 Udinei

  1. Vamos criar um Comparator para definir a forma que queremos organizar os elementos dentro do Map:
class ComparatorPorPreco implements Comparator<Map.Entry<String, Livro>> {
  @Override
  public int compare(Map.Entry<String, Livro> l1, Map.Entry<String, Livro> l2) {
    return Double.compare(l1.getValue().getPreco(), l2.getValue().getPreco());
  }
}
  1. Separamos apenas os valores (objetos do tipo Livro), já que é a partir do atributo preco que vamos querer ordenar nosso Map.

  2. Estamos utilizando o método livros.entrySet() porque queremos que a chave e o valor tenham uma "ligação".

List<Map.Entry<String, Livro>> livrosParaOrdenarPorPreco = new ArrayList<>(livros.entrySet());
  1. Agora que temos uma collection do tipo List, podemos facilmente ordenar esses valores utilizando o Collections:
Collections.sort(livrosParaOrdenarPorPreco, new ComparatorPorPreco());
  1. Já temos os elementos ordenados dentro de um List, porém, precisamos passar novamente para um Map. Para manter a ordem dos elementos a medida que nós inserimos os elementos ordanados dentro de um Map, podemos utilizar a implementação LinkedHashMap.
Map<String, Livro> livrosOrdenadosPorPreco = new LinkedHashMap<>();
  1. Vamos popular o Map livrosOrdenadosPorPreco:
for (Map.Entry<String, Livro> entry : livrosParaOrdenarPorPreco) {
      livrosOrdenadosPorPreco.put(entry.getKey(), entry.getValue());
    }
  1. Agora sim, podemos retornar livrosOrdenadosPorPreco.
public Map<String, Livro> exibirLivrosOrdenadosPorPreco() {
    List<Map.Entry<String, Livro>> livrosParaOrdenarPorPreco = new ArrayList<>(livros.entrySet());

    Collections.sort(livrosParaOrdenarPorPreco, new ComparatorPorPreco());

    Map<String, Livro> livrosOrdenadosPorPreco = new LinkedHashMap<>();

    for (Map.Entry<String, Livro> entry : livrosParaOrdenarPorPreco) {
      livrosOrdenadosPorPreco.put(entry.getKey(), entry.getValue());
    }

    return livrosOrdenadosPorPreco;
  }

Também criei o método exibirLivrosOrdenadosPorAutor():

public Map<String, Livro> exibirLivrosOrdenadosPorAutor() {
    List<Map.Entry<String, Livro>> livrosParaOrdenarPorAutor = new ArrayList<>(livros.entrySet());

    Collections.sort(livrosParaOrdenarPorAutor, new ComparatorPorAutor());

    Map<String, Livro> livrosOrdenadosPorAutor = new LinkedHashMap<>();

    for (Map.Entry<String, Livro> entry : livrosParaOrdenarPorAutor) {
      livrosOrdenadosPorAutor.put(entry.getKey(), entry.getValue());
    }

    return livrosOrdenadosPorAutor;
  }

Veja que é praticamente a mesma coisa. Seguindo os exemplos acima, deixo como desafio, você tentar implementar o método exibirLivrosOrdenadosPorTitulo().

Ah, pode instanciar o new Comparator dentro do método exibirLivrosOrdenadosPorTitulo() como você vem fazendo, ok? Gosto de criar uma classe fora só por organização mesmo. (:

cami-la avatar Sep 11 '23 12:09 cami-la

Bom dia Camila!

Consegui fazer! Esse foi o exemplo mais simples que consegui implementar, os outros ficaram muito complexos!

public void exibirLivrosOrdenadosPorPreco() {
TreeMap<Double, Livro> livrosOrdenados = new TreeMap<>(new Comparator() {

     @Override
        public int compare(Double preco1, Double preco2) {
            return Double.compare(preco1, preco2);
        }
    });

    System.out.println(livrosOrdenados.entrySet());
    for (var entry : livrosMap.entrySet()) {
        Livro livro = entry.getValue();
        double preco = livro.getPreco();
        livrosOrdenados.put(preco, entry.getValue());
    }

    System.out.println(livrosOrdenados);

}`

Oi, @Udinei. Meus parabéns, sua implementação ficou ótima! Porém tem um detalhe: Veja que você modificou o tipo da chave do map: TreeMap<Double, Livro> livrosOrdenados = new TreeMap<>();

No nosso exercício, o Map contém as chave String (que representa o link do Livro) e o valor é o objeto do tipo Livro. Isso é um problema? Não, de forma alguma. Mas acima, implementei de uma outra forma sem modificar o tipo original da chave e valor do Map e te deixei um desafio. (:

De fato, quando queremos ordenar um Map através do value e não da key é um pouco mais trabalhoso. Mas você está indo muito bem! Se ficou alguma dúvida, fico à disposição. E agradeço pela issue, assim eu pude corrigir e melhorar os exercícios.

cami-la avatar Sep 11 '23 12:09 cami-la