Map Ordenação LivrariaOnline - exibirLivrosOrdenadosPorPreco(),
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!!
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);
}`
- Vamos criar um
Comparatorpara definir a forma que queremos organizar os elementos dentro doMap:
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());
}
}
-
Separamos apenas os valores (objetos do tipo
Livro), já que é a partir do atributo preco que vamos querer ordenar nossoMap. -
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());
- Agora que temos uma collection do tipo
List, podemos facilmente ordenar esses valores utilizando oCollections:
Collections.sort(livrosParaOrdenarPorPreco, new ComparatorPorPreco());
- Já temos os elementos ordenados dentro de um
List, porém, precisamos passar novamente para umMap. Para manter a ordem dos elementos a medida que nós inserimos os elementos ordanados dentro de umMap, podemos utilizar a implementaçãoLinkedHashMap.
Map<String, Livro> livrosOrdenadosPorPreco = new LinkedHashMap<>();
- Vamos popular o Map
livrosOrdenadosPorPreco:
for (Map.Entry<String, Livro> entry : livrosParaOrdenarPorPreco) {
livrosOrdenadosPorPreco.put(entry.getKey(), entry.getValue());
}
- 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. (:
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.