(RESOLVIDO)HashMap - Retornar índice do maior valor

16 respostas
Michel_M

Bom dia pessoal…

Estou com uma duvida aqui, espero que vcs possam me ajudar. Eu tenho um hashMap e nele eu quero retornar o indice do maior valor dele.

Ex:

HashMap<Integer,Integer> list = new HashMap<Integer,Integer>();// Primeira Indice e depois o valor list.put(1,10); list.put(2,20); // Maior valor list.put(4,5); list.put(8,11);

Teria que retornar então indice 2.
Vcs sabem como eu posso realizar isto?

Desde já agradeço a todos!

16 Respostas

drsmachado

Creio que precisa usar o iterator, iterar sobre o mesmo e assim ter acesso ao cruzamento das informações.

lele_vader

Usa um treemap que é uma coleção ordenada.
Para isso vai ter que implementar hashcode e equals lá no valor se for um tipo criado por você.

Acredito que vai ter que fazer um comparator também para comparar os valor, pois o treemap acho que é ordenado pela chave.

Michel_M

Pelo que eu entendi vc quer que eu compare um por um, ai ache o maior e retorne o indice. Mais assim eu vou perder uma performance muito grande. O que vc acha de ordenar e assim pegar a primeira posição??.. mais eu não achei uma maneira de pegar a primeira posição.

drsmachado

Pelo que eu entendi vc quer que eu compare um por um, ai ache o maior e retorne o indice. Mais assim eu vou perder uma performance muito grande. O que vc acha de ordenar e assim pegar a primeira posição??.. mais eu não achei uma maneira de pegar a primeira posição.
HashMap não garante ordenação, meu camarada.
Se pretende usar este tipo de coleção, precisa iterar sobre. A sugestão do lele_vader é bacana, vai te dar um trabalho, mas é mais adequada.

lele_vader

Dá uma olhada aqui http://docs.oracle.com/javase/1.4.2/docs/api/java/util/TreeMap.html

Esse tipo de coleção já se ordena.

Daí você pode usar get(0) e vai trazer o seu valor.

Porém, como eu disse o treemap ordena por default pelas chaves, então provavelmente se você instanciar assim com o exemplo que você deu ele vai trazer o valor 1, pois é a primeira chave.
Daí você implementa um comparator que pega os seus valores e retorna o maior ao invés do menor

Michel_M

lele_vader:
Dá uma olhada aqui http://docs.oracle.com/javase/1.4.2/docs/api/java/util/TreeMap.html

Esse tipo de coleção já se ordena.

Daí você pode usar get(0) e vai trazer o seu valor.

Porém, como eu disse o treemap ordena por default pelas chaves, então provavelmente se você instanciar assim com o exemplo que você deu ele vai trazer o valor 1, pois é a primeira chave.
Daí você implementa um comparator que pega os seus valores e retorna o maior ao invés do menor

Teria como vc me mostrar um exemplo?

lele_vader

Olha só

http://www.java-samples.com/showtutorial.php?tutorialid=371

Veja no final que ele ordena pelo último nome e não pelo primeiro nome.

A unica questão que você tem que ver é como ordenar pelos valores e não pelas chaves.

Precisa mesmo desse índice ?

Porque daí poderia usar um hashset que também se ordena.

Michel_M

lele_vader:
Olha só

http://www.java-samples.com/showtutorial.php?tutorialid=371

Veja no final que ele ordena pelo último nome e não pelo primeiro nome.

A unica questão que você tem que ver é como ordenar pelos valores e não pelas chaves.

Precisa mesmo desse índice ?

Porque daí poderia usar um hashset que também se ordena.

Preciso porque esse indice é o ID do registro que eu vou alterar.

E

Note que se você usar um SortedMap qualquer, ele é ordenado pelas chaves, não pelos valores.

Dica 2: não use nomes confusos para variáveis. “list” para representar um “map” vai causar problemas na sua cabeça.

SortedMap<Integer,Integer> map = new TreeMap<Integer,Integer>();
map.put(1,10);    
map.put(2,20); // Maior valor   
map.put(4,5);    
map.put(8,11);

Forma 1 - você pode achar o máximo dos valores usando Collections.max (mas nesse caso você não vai saber a chave correspondente, só o valor):

Integer i = Collections.max (map.values()); // deve ter o valor 20

Forma 2 - se você precisa achar o índice, então você vai ter de varrer a coleção mesmo. Algo como:

int indice = -1, valor = Integer.MIN_VALUE;
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
    if (valor < entry.getValue()) {
        indice = entry.getKey(); valor = entry.getValue();
    }
}
nel

E se inverter o seu map, fazendo a chave ser o valor e “valor” do map ser a chave do seu banco? Ai é muito fácil, veja:

TreeMap<Integer, Integer> map = new TreeMap<Integer, Integer>();
		map.put(10,1);    
		map.put(20,2); // Maior valor   
		map.put(5,4);    
		map.put(11,8);   
		
		System.out.println("Maior valor: " + map.lastKey());
		System.out.println("Chave: " + map.get(map.lastKey()));

Assim tu tem o maior valor e a chave correspondente, sem maiores problemas.

lele_vader

E não pode ser o contrário ?

O valor como chave e a id como valor ?

Porque senão ou você itera tudo e checa ou implementa o seu sortedMap, que é a interface que a coleções de mapa ordenado usam

igual aqui

E

Pode-se inverter um map se ele representar uma relação biunívoca (ou seja, para cada índice corresponde um valor e vice-versa).
Se esse map for inversível não há problemas em usar a solução do Nel.

Michel_M

entanglement:
Pode-se inverter um map se ele representar uma relação biunívoca (ou seja, para cada índice corresponde um valor e vice-versa).
Se esse map for inversível não há problemas em usar a solução do Nel.

Isso msm como indice vai ser o ID do registro ele não vai repetir, mais o valor sim vai poder ser repetido até pq vai ser uma data.

E

Pelo que imagino, você não quer então 1 índice e sim N índices correspondendo ao maior valor, que se repete.

Então o código que passei teria de ser um pouco mais complicado, porque teria de acumular vários índices, correspondentes ao valor máximo, em uma lista.

nel

entanglement:
Pelo que imagino, você não quer então 1 índice e sim N índices correspondendo ao maior valor, que se repete.

Então o código que passei teria de ser um pouco mais complicado, porque teria de acumular vários índices, correspondentes ao valor máximo, em uma lista.

Exatamente. Então não há muita saída (ou talvez seja a única) além de percorrer o map item a item. Se você precisa do maior valor, mesmo que ele repita N vezes e possa ser qualquer índice, o que eu disse acima serve, caso contrário, precisa de uma lógica melhor elaborada.

pmlm

Uma opção é guardares dois maps.
Um “normal” e outro invertido, onde guardas valor - lista de chaves.

Criado 21 de junho de 2012
Ultima resposta 21 de jun. de 2012
Respostas 16
Participantes 6