是否可以通过位置从 HashMap 获取元素?

如何根据位置从 HashMap 检索元素,这可能吗?

202732 次浏览

HashMaps 不保留顺序:

这个类不能保证 地图的顺序; 特别是, 它不能保证命令 将随着时间的推移保持不变。

Take a look at LinkedHashMap, which guarantees a predictable iteration order.

Use LinkedHashMap:

Map 接口的哈希表和链表实现,具有可预测的迭代顺序。这个实现与 HashMap 的不同之处在于,它维护了一个贯穿其所有条目的双链表。

HashMap-和底层数据结构-散列表,没有位置的概念。与 LinkedList 或 Vector 不同,输入键被转换为存储值的“ bucket”。这些桶的排序方式在 HashMap 接口之外是没有意义的,因此,放入 HashMap 中的项目的排序方式与其他数据结构的排序方式不同

HashMap 没有位置的概念,所以没有办法按位置获取对象。映射中的对象是通过键设置和获取的。

我假设通过“ position”您指的是将元素插入到 HashMap 中的顺序。在这种情况下,您需要使用 LinkedHashMap。但是 LinkedHashMap 没有提供访问器方法; 您需要编写一个类似的方法

public Object getElementAt(LinkedHashMap map, int index) {
for (Map.Entry entry : map.entrySet()) {
if (index-- == 0) {
return entry.value();
}
}
return null;
}

HashMaps 不允许按位置访问,它只知道哈希代码,如果它可以计算键的哈希代码,它就可以检索值。TreeMaps 具有排序的概念。Linkedhas 地图保留了它们进入地图的顺序。

Use a LinkedHashMap and when you need to retrieve by position, convert the values into an 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 并使用此函数。

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;
}

该函数可以返回选定的条目。

如果希望保持将元素添加到映射中的顺序,可以使用 LinkedHashMap,而不仅仅使用 HashMap

Here is an approach that will allow you to get a value by its index in the map:

public Object getElementByIndex(LinkedHashMap map,int index){
return map.get( (map.keySet().toArray())[ index ] );
}

你可以尝试实现这样的东西,看看:

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

另一种工作方法是将映射值转换为数组,然后检索索引处的元素。使用以下方法在 LinkedHashMap 中对100000个对象进行索引搜索,测试运行100000个元素,结果如下:

//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,那么可以将 keySet 转换为数组,并对数组中的键进行索引,以获得 map 中的值,如下所示:

Object[] keys = map.keySet().toArray();

然后你就可以像这样访问地图:

map.get(keys[i]);

您可以使用下面的代码来获取密钥: String [] keys = (String[]) item.keySet().toArray(new String[0]);

并获取在 HashMap 中插入的对象或列表,其键为下面的项: item.get(keys[position]);

By default, java LinkedHasMap does not support for getting value by position. So I suggest go with customized 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);