Como recuperar um elemento do HashMap por sua posição, isso é possível?
Como recuperar um elemento do HashMap por sua posição, isso é possível?
Respostas:
HashMaps não preservam a ordem:
Essa classe não oferece garantias quanto à ordem do mapa; em particular, não garante que o pedido permanecerá constante ao longo do tempo.
Dê uma olhada em LinkedHashMap , que garante uma ordem de iteração previsível.
Use um LinkedHashMap e quando precisar recuperar por posição, converta os valores em um ArrayList.
LinkedHashMap<String,String> linkedHashMap = new LinkedHashMap<String,String>();
/* Populate */
linkedHashMap.put("key0","value0");
linkedHashMap.put("key1","value1");
linkedHashMap.put("key2","value2");
/* Get by position */
int pos = 1;
String value = (new ArrayList<String>(linkedHashMap.values())).get(pos);
Se você deseja manter a ordem em que adicionou os elementos ao mapa, use LinkedHashMap
em vez de apenas HashMap
.
Aqui está uma abordagem que permitirá que você obtenha um valor por seu índice no mapa:
public Object getElementByIndex(LinkedHashMap map,int index){
return map.get( (map.keySet().toArray())[ index ] );
}
Se você, por algum motivo, tiver que ficar com o hashMap, poderá converter o keySet em uma matriz e indexar as chaves na matriz para obter os valores no mapa da seguinte maneira:
Object[] keys = map.keySet().toArray();
Você pode acessar o mapa como:
map.get(keys[i]);
String myKey = keys[i].toString();
Use LinkedHashMap
:
Implementação de tabela de hash e lista vinculada da interface Map, com ordem de iteração previsível. Essa implementação difere do HashMap porque mantém uma lista duplamente vinculada em todas as suas entradas.
Use LinkedHashMap e use esta função.
private LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();
Defina assim e.
private Entry getEntry(int id){
Iterator iterator = map.entrySet().iterator();
int n = 0;
while(iterator.hasNext()){
Entry entry = (Entry) iterator.next();
if(n == id){
return entry;
}
n ++;
}
return null;
}
A função pode retornar a entrada selecionada.
Estou supondo que por 'posição' você está se referindo à ordem em que inseriu os elementos no HashMap. Nesse caso, você deseja usar um LinkedHashMap. O LinkedHashMap não oferece um método de acessador; você precisará escrever um like
public Object getElementAt(LinkedHashMap map, int index) {
for (Map.Entry entry : map.entrySet()) {
if (index-- == 0) {
return entry.value();
}
}
return null;
}
Outra abordagem de trabalho é transformar os valores do mapa em uma matriz e, em seguida, recuperar o elemento no índice. A execução de teste de 100.000 elementos por pesquisas de índice em LinkedHashMap de 100.000 objetos usando as seguintes abordagens levou aos seguintes resultados:
//My answer:
public Particle getElementByIndex(LinkedHashMap<Point, Particle> map,int index){
return map.values().toArray(new Particle[map.values().size()])[index];
} //68 965 ms
//Syd Lambert's answer:
public Particle getElementByIndex(LinkedHashMap<Point, Particle> map,int index){
return map.get( (map.keySet().toArray())[ index ] );
} //80 700 ms
Resumindo, recuperar elemento por índice de LinkedHashMap parece ser uma operação bastante pesada.
HashMap - e a estrutura de dados subjacente - tabelas de hash, não têm uma noção de posição. Ao contrário de LinkedList ou Vector, a chave de entrada é transformada em um 'balde' onde o valor é armazenado. Esses depósitos não são ordenados de uma forma que faça sentido fora da interface HashMap e, como tal, os itens que você coloca no HashMap não estão em ordem no sentido que você esperaria com outras estruturas de dados
O HashMap não tem conceito de posição, portanto, não há como obter um objeto por posição. Os objetos no Maps são definidos e obtidos por teclas.
Por padrão, java LinkedHasMap não suporta a obtenção de valor por posição. Então, eu sugiro ir com personalizadoIndexedLinkedHashMap
public class IndexedLinkedHashMap<K, V> extends LinkedHashMap<K, V> {
private ArrayList<K> keysList = new ArrayList<>();
public void add(K key, V val) {
super.put(key, val);
keysList.add(key);
}
public void update(K key, V val) {
super.put(key, val);
}
public void removeItemByKey(K key) {
super.remove(key);
keysList.remove(key);
}
public void removeItemByIndex(int index) {
super.remove(keysList.get(index));
keysList.remove(index);
}
public V getItemByIndex(int i) {
return (V) super.get(keysList.get(i));
}
public int getIndexByKey(K key) {
return keysList.indexOf(key);
}
}
Então você pode usar este LinkedHasMap personalizado como
IndexedLinkedHashMap<String,UserModel> indexedLinkedHashMap=new IndexedLinkedHashMap<>();
PARA adicionar valores
indexedLinkedHashMap.add("key1",UserModel);
Para obter o valor por índice
indexedLinkedHashMap.getItemByIndex(position);
HashMaps não permitem acesso por posição, ele só conhece o código hash e pode recuperar o valor se puder calcular o código hash da chave. TreeMaps tem uma noção de ordenação. Os mapas do Linkedhas preservam a ordem em que entraram no mapa.
Você pode tentar implementar algo assim, observe:
Map<String, Integer> map = new LinkedHashMap<String, Integer>();
map.put("juan", 2);
map.put("pedro", 3);
map.put("pablo", 5);
map.put("iphoncio",9)
List<String> indexes = new ArrayList<String>(map.keySet()); // <== Parse
System.out.println(indexes.indexOf("juan")); // ==> 0
System.out.println(indexes.indexOf("iphoncio")); // ==> 3
Espero que isso funcione pra você.