Como ordenar um Map pelo valor em ves da chave

olá,
tenho um HashMap<Character, Integer>
queria uma maneira de saber qual chave tem o menor valor, para depois excluí-la,
usei o TreeMap, mas ele ordena pela ordem alfabética.
tem como ele ordenar pelos valores Integer? ou tenho de implementar aquele tal de Coparator?

outra dúvida, achei uma classe PriorityQueue, que é uma fila que ordena pelo menor. consegui usá-la com array, mas não consegui com o meu HashMap, é porque hashMap não é uma Collection? teria como eu usar o hashMap nessa classe?

obrigado!

se nao to enganado Map trabalha baseado em chaves e nao valores… é tanto que vc pode ter valores iguais para chaves diferentes…acho q vc nao pode ordenar pelo valor…

Tem um jeito sim… É meio gambiarrento, mas fica estiloso…

Primeiro, tu vai ter que criar uma nova classe, herdando de HashMap:

class SortedHashMap<E, T> extends HashMap<E, T> {
    public Iterator<Object> iterator() {
        Collection<T> collection = this.values();
        Object[] array = collection.toArray();
        Arrays.sort(array);
        return Arrays.asList(array).iterator();
    }
}

Depois, é só usar essa classe pra fazer seu map:

SortedHashMap<Character, Integer> map = new SortedHashMap<Character, Integer>();
map.put(new Character('a'), new Integer(5));
map.put(new Character('b'), new Integer(1));
map.put(new Character('c'), new Integer(3));
map.put(new Character('d'), new Integer(4));
map.put(new Character('e'), new Integer(2));

Daí para buscar os valores, é só usar esse iterator() que a classe SortedHashMap sobrescreveu…

Iterator iter = map.iterator();
while (iter.hasNext()) {
    System.out.println(iter.next()); // Ou qualquer outra coisa
}

Peguei esse código desse site aqui: http://www.codeguru.com/forum/archive/index.php/t-284510.html
E dei uma modificada pra encaixar naquilo que tu precisava…

Té mais o/
(Testa e depois comenta se funcionou ou não…)

nao pensei na gambiarra… :smiley:

infelizmente não era o que eu queria, mas obrigado pela ajuda, esse código ordenou pelos valores, mas só mostrou os valores. eu queria que mostrasse os pares chave=valor.
mas eu consegui, até que enfim, fazer algo, eu queria excluir a chave que tivesse menor valor, e acho queconsegui, depois de pensar muito.
sou muito iniciante, então queria que descem uma olhada no código e fizessem críticas, sei que tá ruim o código.

imagino que isso seja gambiarra, eu criei um objeto Letra que implementei comparator, que tem variaveis de instância chave e valor.
peguei as chaves do HashMap para criar os objetos Letra e inseri num PriorityQueue (que faz exatamente oque eu queria), depois é só eu excluir.

[code]public class ExcluirMenor{
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
StringBuffer string = new StringBuffer();
PriorityQueue fila = new PriorityQueue();

public void contCaracteres(String fileName) {
	try{
		BufferedReader file = new BufferedReader(new FileReader(fileName));
		String linha = null;
		while((linha = file.readLine()) != null){
			string.append(linha);
		}
	}catch (Exception e) {
		e.printStackTrace();
	}
	//imprime um teste.
	System.out.println(string);

	for(int i=0; i<string.length(); i++){
		if((map.get(string.charAt(i)) == null)){
			map.put(string.charAt(i), 1);
		}else{
			map.put(string.charAt(i), map.get(string.charAt(i)) + 1);
		}
	}
	//imprime um teste
	System.out.println(map.toString());

	for(Character character: map.keySet()){
		fila.offer(new Letra(character, map.get(character)));
	}
	//imprime um teste
	while(fila.size() > 0){
		System.out.println(fila.peek().toString()+"   eh esse óhh!!!");
		fila.poll();
	}
}

}[/code]

[code]//classe Letra
public class Letra implements Comparable{
private Character chave;
private Integer valor;

public Character getChave() {
	return chave;
}
public void setChave(Character chave) {
	this.chave = chave;
}
public int getValor() {
	return valor;
}
public void setValor(Integer valor) {
	this.valor = valor;
}

public Letra(Character chave, Integer valor) {
	super();
	this.chave = chave;
	this.valor = valor;
}
public String toString() {
	return (chave+"="+valor);
}
public int compareTo(Object o) {
	Letra letra = (Letra)o;
	return this.valor.compareTo(letra.valor);
}

}[/code]

Obrigado!!

Como postula a segunda lei de POG :

A gambiarra primária consistia em usar o valor do mapa para classificar os elementos (quando o correto seria utilizar a chave pra isso). A criação de um objeto próprio pra isso foi uma boa saída, que eu não tinha pensado. Acho que é até mais correta, pro utilização que tu pretende.

Só uma pergunta: Agora que tu já criou o objeto próprio, não poderias abolir o HashMap do teu programa? Poderias usar, quem sabe, um Collection mais apropriado, como um conjunto ou uma lista…

Abraços

cara, na verdade eu nem sei, mas se tu acha deve ser porque dá certo. é que não sei muita coisa, na verdade nem sei como meu código deu certo.

Valeus!

Acho que está um pouco tarde, mas deixo aqui pra quem quiser, um código que fiz, que ordena Maps por chaves ou valores, com suporte a Generics do Java 5.

MapUtils.

e para usar entao:

SortedHashMap<Character, Integer> map = new SortedHashMap<Character, Integer>();
map.put(new Character('a'), new Integer(5));
map.put(new Character('b'), new Integer(1));
map.put(new Character('c'), new Integer(3));
map.put(new Character('d'), new Integer(4));
map.put(new Character('e'), new Integer(2));

Map ordenado = MapUtils.sortMapByValue(map);

//prontinho, só usar o ordenado agora :)

PS: Postei o link porque o código é extenso.

Saudações

Para não criar outro tópico, estou ressuscitando esse. Utilizei a classe MapUtils acima, porém não consegui ordenar meu map pelo valor.

tenho, atraves da API do jung, vários pares, do tipo Pair<String>, onde cada objeto contém dois tipos de objetos, no caso, uma string. Devo contar a frequencia de cada par e colocar o respectivo par com sua frequencia num map. A contagem está ok, mas sempre que faço map.put(par, 2) por exemplo, o número de registros dentro map do tipo null aumenta. O que estou fazendo/deixando de fazer para que isso aconteça?

Como não consegui ordenar pelo valor, creio que pode ter alguma relação com a quantidade de nulls dentro do map…

[size=18]Porque que tem tanta gente que gosta de reinventar a roda quadrada?[/size]

Você não precisa criar uma classe ou fazer uma gabiarra para isso. É só usar o que o Java 6 já tem prontinho, bem testado e abençoado pelo JCP:

http://java.sun.com/javase/6/docs/api/java/util/SortedMap.html
http://java.sun.com/javase/6/docs/api/java/util/NavigableMap.html

[quote=victorwss][size=18]Porque que tem tanta gente que gosta de reinventar a roda quadrada?[/size]

Você não precisa criar uma classe ou fazer uma gabiarra para isso. É só usar o que o Java 6 já tem prontinho, bem testado e abençoado pelo JCP:

http://java.sun.com/javase/6/docs/api/java/util/SortedMap.html
http://java.sun.com/javase/6/docs/api/java/util/NavigableMap.html[/quote]

E seu quiser ordenar no java 1.4? :stuck_out_tongue: :stuck_out_tongue: :stuck_out_tongue: :stuck_out_tongue:

Voltando ao assunto vc nao poderia implementar um Comparator?

já implementei para utilizar com a classe MapUtils acima, porém não funcionou… o Comparator que implementei compara o valor, não a chave.

EDIT:
http://java.sun.com/javase/6/docs/api/java/util/TreeMap.html#TreeMap(java.util.Comparator)

[quote=victorwss][size=18]Porque que tem tanta gente que gosta de reinventar a roda quadrada?[/size]

Você não precisa criar uma classe ou fazer uma gabiarra para isso. É só usar o que o Java 6 já tem prontinho, bem testado e abençoado pelo JCP:

http://java.sun.com/javase/6/docs/api/java/util/SortedMap.html
http://java.sun.com/javase/6/docs/api/java/util/NavigableMap.html[/quote]
quero ordenar os valores, não as chaves.

[quote=victorwss][size=18]Porque que tem tanta gente que gosta de reinventar a roda quadrada?[/size]

Você não precisa criar uma classe ou fazer uma gabiarra para isso. É só usar o que o Java 6 já tem prontinho, bem testado e abençoado pelo JCP:

http://java.sun.com/javase/6/docs/api/java/util/SortedMap.html
http://java.sun.com/javase/6/docs/api/java/util/NavigableMap.html[/quote]

Humm… talvez porque não a está inventando. :twisted: Do javadoc do SortedMap

Todas as implementações ordenáveis de mapas ordenas as chaves. O que se está querendo é ordenar os valores.

EDIT: Ou seja, pode tentar isso:
Map<K, V> map = …;
Collections.sort(map.values());

isso mesmo. quero ordenar um map através dos valores.

EDIT: Ou seja, pode tentar isso:
Map<K, V> map = …;
Collections.sort(map.values());[/quote]
vou testar e postar o resultado.

Exatamente seria o caso de implementar um Comparator.

Um link que pode te ajudar: http://paaloliver.wordpress.com/2006/01/24/sorting-maps-in-java/

[quote=ramilani12]Exatamente seria o caso de implementar um Comparator.

Um link que pode te ajudar: http://paaloliver.wordpress.com/2006/01/24/sorting-maps-in-java/[/quote]

Exatamente isso. :smiley: