ÁrvoreMapa:Classifique os valores de um mapa com chaves movendo-se junto com os valores
-
23-09-2019 - |
Pergunta
eu tenho o seguinte TreeMap:
TreeMap<Integer, Double> map;
os valores Double não são exclusivos.
eu itero pelo mapa usando teclas inteiras e as funções firstEntry() e lowerEntry() e modifico os valores Double.
Agora quero listar os valores dos pares em ordem decrescente de valores Double.qual é a melhor maneira de fazer isso?
essas chaves inteiras são importantes para mim e como os valores Double não são exclusivos, não posso ter uma chave Double.
Atualizar:Mais explicação é o problema clássico.digamos que rollnos de alunos seja a chave e sua porcentagem seja o valor.agora classifique por porcentagem e então poderemos dizer de quem é a porcentagem.portanto, preciso da chave inteira.
Solução
você pode construir um TreeSet
, que garante o pedido de inserção:
@Test
public void treeMapSortedByValue() {
// given the following map:
TreeMap<Integer, Double> map = new TreeMap<Integer, Double>();
map.put(2, Math.E);
map.put(1, Math.PI);
map.put(3, 42.0);
// build a TreeSet of entries
Set<Map.Entry<Integer, Double>> sortedEntries = new TreeSet<Map.Entry<Integer, Double>>(new DoubleComparator());
sortedEntries.addAll(map.entrySet());
// optionally you can build a List<Double> with the sorted
List<Double> doubles = new LinkedList<Double>();
for (Map.Entry<Integer, Double> entry : sortedEntries) {
doubles.add(entry.getValue());
}
}
isso deve lhe dar: [2.718281828459045, 3.141592653589793, 42.0]
(nota: [Math.E, Math.PI, Math.UNIVERSAL_ANSWER]
:-).
PS
o Comparator
:
class DoubleComparator implements Comparator<Map.Entry<Integer, Double>> {
@Override
public int compare(Entry<Integer, Double> o1, Entry<Integer, Double> o2) {
return Double.compare(o1.getValue(), o2.getValue());
}
}
Outras dicas
A solução óbvia é obter uma coleção de duplos (possivelmente através do - a classe TreeMap tem um entrySet
e então getValue
values()
método, você pode simplesmente usá-lo) e prosseguir para classificá-los (usando Collections.sort
ou Arrays.sort
) - isso levaria, no entanto, tempo O(n logn).
Não tenho certeza se você pode fazer isso de maneira mais inteligente (== mais rápida), a menos que altere completamente a estrutura de dados.No entanto, a única maneira pela qual vejo isso acontecendo com outra estrutura de dados é manter um wrapper sobre o inteiro e o duplo e escrever dois comparadores - um que compara o integer
e aquele que compara primeiro pelo double
e depois pelo integer
.O TreeMap original que você está usando seria o mesmo, mas você seria capaz de separar outro TreeMap dele, classificado pelo segundo comparador.A desconexão ainda levaria tempo O(n logn).
O que você pode fazer é o seguinte: Use entrada de entrada para itera através das entradas. Coloque -os em uma lista. Classifique a data com o comparador certo então.