こんにちは、名前/年齢(文字列/整数)のペアを含むLinkedHashMap(情報と呼ばれる)があります。キーを入力した場合、どのようにしてキー/値の位置を取得できますかを知りたいです。たとえば、LinkedHashMapが{bob = 12、jeremy = 42、carly = 21}のように見え、jeremyを検索する場合、位置1として1を返す必要があります。info.getIndexのようなものを使用できると期待していました(「ジェレミー」)
HashMap
の実装は、一般的にIteration
の順序付けられていません。
LinkedHashMap
は予測可能Iteration
(挿入順序)の順序ですが、List
インターフェイスとLinkedList
(キーセットの挿入順序を反映するもの)は、インデックスの位置自体も追跡しません。インデックスを見つけることも非常に非効率的です。 LinkedHashMap
は、内部LinkedList
への参照も公開しません。
実際の "リンクリスト"の動作は実装固有です。実際に
LinkedList
のインスタンスを使用する人もいれば、直前と次のEntry
を追跡するEntry
を持つだけで、その実装として使用する人もいます。ソースを見ないで何も仮定しないでください。
キーを含むKeySet
は、継承されたHashMap
のバッキングデータ構造に配置するために使用されるハッシュアルゴリズムのため、順序も保証しません。だからそれは使えない。
独自の実装を作成せずにこれを行う唯一の方法は、ミラーリングIterator
を使用するLinkedList
を歩いて、現在の場所でカウントを維持することです。データセット。
ソリューション
あなたが望むように聞こえるのは、元の挿入順序のインデックス位置、KeySet
のようなものでArrayList
のキーをミラーリングする必要があり、同期を保つことです。 HashMap
を更新して、位置を見つけるために使用します。 HashMap
のサブクラスを作成し、たとえばIndexedHashMap
を作成し、このArrayList
を内部で追加し、内部ArrayList
に委任する.getKeyIndex(<K> key)
を追加します.indexOf()
はおそらくこれを行うための最良の方法です。
これはLinkedHashMap
が行うことですが、LinkedList
の代わりにKeySet
をミラーリングするArrayList
を使用します。
int pos = new ArrayList<String>(info.keySet()).indexOf("jeremy")
LinkedHashMapには「予測可能な反復順序」があります( javadoc )。ただし、アイテムはその場所を知らないため、コレクションを取得して取得する必要があります。大きなマップを維持している場合は、ストレージに別の構造を使用することをお勧めします。
編集:明確化された反復
Google Guavaライブラリの _com.google.common.collect.LinkedListMultimap
_ を使用できます。このクラスのマルチマップの動作は必要ありません。keys()
メソッドが挿入順序で返されることを保証し、リストの作成に使用できることです。indexOf()
必要なインデックス位置を見つける
私はこの質問の重複の1つからの提案を見ました
キーではなくインデックスに基づいてLinkedHashMapから値を取得する方法
また、コメントで@schippiからの擬似コードとして説明されている提案が気に入りました。私はいくつかの作業Javaこのコードで他の人に役立つかもしれないコードだと思った
import Java.util.ArrayList;
import Java.util.LinkedHashMap;
public class IndexedLinkedHashMap<K,V> extends LinkedHashMap<K,V> {
/**
*
*/
private static final long serialVersionUID = 1L;
ArrayList<K> al_Index = new ArrayList<K>();
@Override
public V put(K key,V val) {
if (!super.containsKey(key)) al_Index.add(key);
V returnValue = super.put(key,val);
return returnValue;
}
public V getValueAtIndex(int i){
return (V) super.get(al_Index.get(i));
}
public K getKeyAtIndex(int i) {
return (K) al_Index.get(i);
}
public int getIndexOf(K key) {
return al_Index.indexOf(key);
}
}