位置によってHashMapから要素を取得する方法、それはまったく可能ですか?
位置によってHashMapから要素を取得する方法、それはまったく可能ですか?
回答:
HashMapは順序を保持しません。
このクラスは、マップの順序については保証しません。特に、順序が長期にわたって一定であることを保証するものではありません。
予測可能な反復順序を保証する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);
何らかの理由でhashMapを使用する必要がある場合は、keySetを配列に変換し、配列内のキーにインデックスを付けて、次のようにマップ内の値を取得できます。
Object[] keys = map.keySet().toArray();
その後、次のようにマップにアクセスできます。
map.get(keys[i]);
String myKey = keys[i].toString();
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;
}
関数は、選択したエントリを返すことができます。
別の実用的なアプローチは、マップ値を配列に変換してから、インデックスで要素を取得することです。以下のアプローチを使用した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からインデックスによって要素を取得することは、かなり重い操作のようです。
デフォルトでは、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は位置によるアクセスを許可しません。ハッシュコードについてのみ認識し、キーのハッシュコードを計算できる場合は値を取得できます。ツリーマップには順序付けの概念があります。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
これがうまくいくことを願っています。