Ordenando um Map pelo Valor  XML
Índice dos Fóruns » Java Avançado
Autor Mensagem
cezarsg
JavaChild

Membro desde: 28/04/2003 09:57:38
Mensagens: 129
Localização: curitiba
Offline

Pessoal, preciso ordenar um Map pelo valor. Qual o segredo???
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

Se você usar um SortedMap ele é ordenado pela chave, não pelo valor.
Para ordenar um SortedMap pelo valor, faça um mapa "reverso", trocando os valores pelas chaves. Por exemplo:

[WWW]
ramilani12
GUJ Master
[Avatar]

Membro desde: 11/03/2005 01:23:30
Mensagens: 1944
Localização: Curitiba-PR
Offline

Se ordenação do Map é para apresentação vc pode utilizar o método Collections.sort()
Vejamos:



my delicious|follow me|linkedin
[Email] [ICQ]
cezarsg
JavaChild

Membro desde: 28/04/2003 09:57:38
Mensagens: 129
Localização: curitiba
Offline

thingol wrote:Se você usar um SortedMap ele é ordenado pela chave, não pelo valor.
Para ordenar um SortedMap pelo valor, faça um mapa "reverso", trocando os valores pelas chaves. Por exemplo:



Thingol,
Estou usando o java 1.3, daí tentei converter seu código. Ah, fiz uma correção: no laço for, eu faço referência ao map numeros, né?!

Ele só ordena as chaves, mas eu preciso passar esse map para um método processá-lo e com as chaves invertidas daria crash.



thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

Pergunta boba número um - por que é que o tal método precisa de um mapa ordenado pelos valores? Não faz sentido (principalmente se o método receber um Map qualquer, inclusive um HashMap, que não tem ordenação nenhuma).
[WWW]
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

Outra coisa, quando inverto um mapa, como foi o caso que mostrei, estou supondo que há uma relação biunívoca (ou seja, a cada chave corresponde exatamente um valor, e a cada valor corresponde exatamente uma chave).

No exemplo que mostrei não há o tal problema; mas imagine se o mapa fosse, por exemplo, "estado" -> "milhões de habitantes". Por exemplo:

SP -> 23
RJ -> 20
MG -> 20
ES -> 3

Ao inverter o mapa teríamos algo que não é válido para um Map, que é ter 2 chaves iguais. Nesse caso um dos pares seria perdido:

23 -> SP
20 -> MG (o valor RJ -> 20 seria perdido)
3 -> ES

[WWW]
cezarsg
JavaChild

Membro desde: 28/04/2003 09:57:38
Mensagens: 129
Localização: curitiba
Offline

thingol wrote:Outra coisa, quando inverto um mapa, como foi o caso que mostrei, estou supondo que há uma relação biunívoca (ou seja, a cada chave corresponde exatamente um valor, e a cada valor corresponde exatamente uma chave).

No exemplo que mostrei não há o tal problema; mas imagine se o mapa fosse, por exemplo, "estado" -> "milhões de habitantes". Por exemplo:

SP -> 23
RJ -> 20
MG -> 20
ES -> 3

Ao inverter o mapa teríamos algo que não é válido para um Map, que é ter 2 chaves iguais. Nesse caso um dos pares seria perdido:

23 -> SP
20 -> MG (o valor RJ -> 20 seria perdido)
3 -> ES


Não tinha pensando nesse lance da relação biunívoca, e como meu map tem valores repetidos, então não funcionará fazer a inversão. Depois q eu gero esse map, preciso ordená-lo para gerar uma combobox para o usuário.
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

Ah, então é melhor fazer o seguinte:
Gere um List, ou um LinkedHashMap, com base nos pares <chave, valor>. Esse List é que deve ser o tal combo. Por exemplo, digamos que você queira mostrar o combo dos estados ordenados decrescentemente pela população:

SP -> 23
RJ -> 20
MG -> 20
ES -> 2

O LinkedHashMap é um HashMap, mas ele preserva a ordem de inserção (o Iterator retornado por entrySet() retorna os pares chave -> valor na ordem em que foram inseridos, e o Iterator retornado por keySet, as chaves na ordem em que foram inseridas.
Então se você, de alguma forma (talvez usando uma lista temporária) tem esses dados ordenados do jeito que você quer, você pode ter o tal "mapa ordenado pelos valores" que você queria ter.
[WWW]
cezarsg
JavaChild

Membro desde: 28/04/2003 09:57:38
Mensagens: 129
Localização: curitiba
Offline

Achei uma solução, usando a interface Comparator onde consulto o map original para indicar a ordem dos elementos, mas transfiro os itens do map original para um novo map para acontecer a ordenação


Classe ValueComparator:

thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

Obviamente que o meu chutômetro quanto à população dos Estados está bem ruinzinho. No site do IBGE, a população estimada (em 2005) para cada um dos Estados:

SP -> 40.442.795
RJ -> 15.383.407
ES -> 3.408.365
MG -> 19.237.450

Somando RJ e ES dá a população de MG.
[WWW]
#@®®¡$
Moderador
[Avatar]

Membro desde: 13/02/2004 09:42:28
Mensagens: 807
Localização: São Paulo
Offline

thingol wrote:Ah, então é melhor fazer o seguinte:
Gere um List, ou um LinkedHashMap...


O Cezar já resolveu o problema dele, mas só um aviso: ele disse que está usando Java 1.3 e o LinkedHashMap só foi inserido no JDK a partir do 1.4 .

Descobri isso do jeito difícil, ao fazer uma aplicação com o JDK 1.4, compilar com o target 1.3 e aparecer um Error 500: LinkedHashSet .
[WWW] [ICQ]
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

Tanto é que em um sistema em que estava trabalhando o meu chefe tinha criado uma classe com o nome "HashMapOrder" e aproximadamente com a mesma funcionalidade de LinkedHashMap, só que não teve o cuidado de fazê-la implementar a interface Map, e outras mancadas.
[WWW]
 
Índice dos Fóruns » Java Avançado
Ir para:   
Powered by JForum 2.1.8 © JForum Team