位置によってHashMapから要素を取得することは可能ですか?


98

位置によってHashMapから要素を取得する方法、それはまったく可能ですか?


11
「ポジション」とはどういう意味ですか?HashMapは順序付けされていないため、Vectorのようなもので得られる通常の「位置」の概念はありません。
マット

1
その挿入順序または他の順序で意味しますか?
Mark Elliot

回答:


93

HashMapは順序を保持しません。

このクラスは、マップの順序については保証しません。特に、順序が長期にわたって一定であることを保証するものではありません。

予測可能な反復順序を保証するLinkedHashMapを見てください


16
これは実際には質問の答えにはなりません。以下の他の回答がより有用です。
forresthopkinsa 2017年

6
敬意を表して、これは質問に直接答えるドキュメントを引用しています
Wayne

1
時間の経過に伴って順序が一定でなくても、特定の位置でメンバーの1つを取得することは可能です。
2017年

私はついていません。説明する?
ウェイン

HashMapリンクが壊れている/ 404。
Raf

109

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

2
HashMapからキーのコピーをインスタンス化するには常に必要ですか?
Richard

これにより、値を取得するたびに新しいArrayListオブジェクトが作成され、メモリリークが発生します
NullByte08

48

要素をマップに追加した順序を維持したい場合は、ではLinkedHashMapなくを使用してくださいHashMap

以下は、マップ内のインデックスによって値を取得できる方法です。

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

1
最も簡単に言う必要があります...すべてのものを変換する代わりに、キーセットのみを使用しています。素晴らしい
kirtan403

19

何らかの理由でhashMapを使用する必要がある場合は、keySetを配列に変換し、配列内のキーにインデックスを付けて、次のようにマップ内の値を取得できます。

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

その後、次のようにマップにアクセスできます。

map.get(keys[i]);

arr [i]を次のように変更する必要があることに注意してください:keys [i]
Mohsen Abasi 2018年

[OK]を、私は彼らの1を取得するには、マップのキーとして文字列を持っている、第二部は次のようになりますString myKey = keys[i].toString();
Orici

12

使用LinkedHashMap

Mapインターフェースのハッシュテーブルとリンクリストの実装、予測可能な反復順序。この実装は、すべてのエントリで実行される二重リンクリストを維持するという点でHashMapとは異なります。


27
順序は保持されますが、インデックスでアイテムにアクセスすることはできません。あなたは反復する必要があるだろう
Bozho

このリンクは古いバージョンのAPIへのリンクです。Java 6または7 APIにリンクすることをお勧めします。
jzd

6

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

関数は、選択したエントリを返すことができます。


3

「位置」とは、要素をHashMapに挿入した順序を指していると想定しています。その場合は、LinkedHashMapを使用する必要があります。ただし、LinkedHashMapにはアクセサメソッドはありません。次のように書く必要があります

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

3

別の実用的なアプローチは、マップ値を配列に変換してから、インデックスで要素を取得することです。以下のアプローチを使用した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からインデックスによって要素を取得することは、かなり重い操作のようです。


2

HashMap-および基礎となるデータ構造-ハッシュテーブルには、位置の概念はありません。LinkedListやVectorとは異なり、入力キーは値が格納される「バケット」に変換されます。これらのバケットは、HashMapインターフェースの外側で意味のある方法で順序付けられていないため、HashMapに入れたアイテムは、他のデータ構造で期待される意味で順序付けされていません


2

HashMapには位置の概念がないため、位置によってオブジェクトを取得する方法はありません。マップ内のオブジェクトは、キーによって設定および取得されます。


2

以下のコードを使用してキーを取得できます: String [] keys = (String[]) item.keySet().toArray(new String[0]);

次のように、このアイテムのキーを使用してHashMapに挿入するオブジェクトまたはリストを取得します。 item.get(keys[position]);


2

デフォルトでは、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);

1

HashMapは位置によるアクセスを許可しません。ハッシュコードについてのみ認識し、キーのハッシュコードを計算できる場合は値を取得できます。ツリーマップには順序付けの概念があります。Linkedhasマップは、マップに入った順序を保持します。


0

あなたはそのようなものを実装しようとすることができます、見てください:

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

これがうまくいくことを願っています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.