Как получить элемент из HashMap по его позиции, возможно ли это вообще?
Как получить элемент из HashMap по его позиции, возможно ли это вообще?
Ответы:
HashMaps не сохраняют порядок:
Этот класс не дает никаких гарантий относительно порядка карты; в частности, это не гарантирует, что порядок останется постоянным с течением времени.
Взгляните на LinkedHashMap , который гарантирует предсказуемый порядок итераций.
Используйте LinkedHashMap, и когда вам нужно получить по позиции, преобразуйте значения в 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);
Если вы хотите сохранить порядок, в котором вы добавляли элементы на карту, используйте LinkedHashMap
вместо просто HashMap
.
Вот подход, который позволит вам получить значение по его индексу на карте:
public Object getElementByIndex(LinkedHashMap map,int index){
return map.get( (map.keySet().toArray())[ index ] );
}
Если вам по какой-то причине необходимо придерживаться hashMap, вы можете преобразовать keySet в массив и проиндексировать ключи в массиве, чтобы получить значения на карте следующим образом:
Object[] keys = map.keySet().toArray();
Затем вы можете получить доступ к карте, например:
map.get(keys[i]);
String myKey = keys[i].toString();
Использование LinkedHashMap
:
Реализация хэш-таблицы и связанного списка интерфейса Map с предсказуемым порядком итераций. Эта реализация отличается от HashMap тем, что поддерживает двусвязный список, проходящий через все его записи.
Используйте LinkedHashMap и используйте эту функцию.
private LinkedHashMap<Integer, String> map = new LinkedHashMap<Integer, String>();
Определите вот так и.
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;
}
Функция может вернуть выбранную запись.
Я предполагаю, что под «позицией» вы имеете в виду порядок, в котором вы вставили элементы в HashMap. В этом случае вы хотите использовать LinkedHashMap. Однако LinkedHashMap не предлагает метода доступа; вам нужно будет написать что-то вроде
public Object getElementAt(LinkedHashMap map, int index) {
for (Map.Entry entry : map.entrySet()) {
if (index-- == 0) {
return entry.value();
}
}
return null;
}
Другой рабочий подход - преобразование значений карты в массив с последующим извлечением элемента по индексу. Тестовый запуск 100 000 элементов путем поиска по индексу в LinkedHashMap 100 000 объектов с использованием следующих подходов привел к следующим результатам:
//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
В целом получение элемента по индексу из LinkedHashMap кажется довольно сложной операцией.
HashMap - и лежащая в основе структура данных - хеш-таблицы не имеют понятия позиции. В отличие от LinkedList или Vector, ключ ввода преобразуется в «корзину», в которой сохраняется значение. Эти корзины не упорядочены таким образом, который имеет смысл за пределами интерфейса HashMap, и поэтому элементы, которые вы помещаете в HashMap, не упорядочены в том смысле, который вы ожидали бы с другими структурами данных.
HashMap не имеет понятия позиции, поэтому нет возможности получить объект по позиции. Объекты в Картах устанавливаются и достаются ключами.
По умолчанию java LinkedHasMap не поддерживает получение значения по позиции. Поэтому я предлагаю использовать индивидуальныеIndexedLinkedHashMap
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);
}
}
Затем вы можете использовать эту настроенную LinkedHasMap как
IndexedLinkedHashMap<String,UserModel> indexedLinkedHashMap=new IndexedLinkedHashMap<>();
ЧТОБЫ добавить значения
indexedLinkedHashMap.add("key1",UserModel);
Получить значение по индексу
indexedLinkedHashMap.getItemByIndex(position);
HashMaps не разрешает доступ по позиции, он знает только о хэш-коде и может получить значение, если он может вычислить хеш-код ключа. В TreeMaps есть понятие упорядочивания. Карты Linkedhas сохраняют порядок, в котором они были введены на карту.
Можно попробовать реализовать что-то подобное, посмотрите:
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
Надеюсь, это сработает для вас.