【发布时间】:2011-07-11 08:40:23
【问题描述】:
如何通过位置从HashMap中检索元素,有可能吗?
【问题讨论】:
-
“位置”是什么意思? HashMaps 没有顺序,因此它们没有通常的“位置”概念,您可以使用 Vector 之类的东西。
-
你是指它的插入顺序还是其他顺序?
如何通过位置从HashMap中检索元素,有可能吗?
【问题讨论】:
使用 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();
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;
}
函数可以返回选中的条目。
【讨论】:
默认情况下,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);
【讨论】:
我假设“位置”是指将元素插入 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 没有位置的概念,因此无法按位置获取对象。 Maps 中的对象是通过键设置和获取的。
【讨论】:
您可以使用以下代码获取密钥:
String [] keys = (String[]) item.keySet().toArray(new String[0]);
并使用此项目的键获取插入 HashMap 的对象或列表,如下所示:
item.get(keys[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
我希望这对你有用。
【讨论】: