2

私は Java のドキュメントと、LinkedHashMaps がkeyset()順序を維持していることをこの投稿で読みました。 LinkedHashMap オブジェクトからキーと値が返される順序は保証されていますか?

私の質問は、それが順序を保証するのであれば、なぜのソースコードが のような順序を保証するLinkedHashMapタイプのオブジェクトを返さないのですか?SetLinkedHashSet

私が考えることができる理由の 1 つは、LinkedHashSet がメモリ割り当てを増やすマップを使用することです (AbstractSet の実装方法によって異なります)。キーセットの将来の実装を証明するためでもありますか?

この回答がこの投稿で述べているように:リストまたはコレクションを使用する方が良いですか?

リストを返すことは、最適なインターフェイスへのプログラミングと一致しています。

コレクションを返すと、返されるコレクションがセット、リスト、またはキューのいずれかになる可能性があるため、ユーザーにはあいまいさが生じます。

では、のドキュメントを読まずに、keyset()これは曖昧ではありませんか?

keyset()ソースコード:

public Set<K> keySet() {
    Set<K> ks = keySet;
    return (ks != null ? ks : (keySet = new KeySet()));
}

private final class KeySet extends AbstractSet<K> {
    public Iterator<K> iterator() {
        return newKeyIterator();
    }
    public int size() {
        return size;
    }
    public boolean contains(Object o) {
        return containsKey(o);
    }
    public boolean remove(Object o) {
        return HashMap.this.removeEntryForKey(o) != null;
    }
    public void clear() {
        HashMap.this.clear();
    }
}
4

3 に答える 3

5

Setインターフェイスで定義された を返しMapます。ASetは、重複する要素を含まない単純なコレクションです。一方、 aListは順序付きコレクション (シーケンスとも呼ばれます) です。インターフェイスは、List要素が一意であることを指定しません。

それでも、LinkedHashMap実装は実際には基になる keySet を返します。これはLinkedKeySetであり、のforEach()メソッドLinkedKeySetは順序を保持します。つまり、次のようになります。

//from the source code for the LinkedHashMap:
public Set<K> keySet() {
    Set<K> ks;
    return (ks = keySet) == null ? (keySet = new LinkedKeySet()) : ks;
}

したがって、この場合、要素は一意であり、順序付けられています。

于 2016-02-08T17:26:22.387 に答える
5

「 のソース コードが のような順序を保証する型をLinkedHashMap返さないのはなぜですか?」ObjectSetLinkedHashSet

LinkedHashSetは独自のデータを保持する独自の実装を持つ具象クラスであり、keyset()メソッドは のビューを返す必要があるためMap、キー データを にコピーすることはできませんLinkedHashSet。javadoc を参照してください:

Setこのマップに含まれるキーのビューを返します。セットはマップによってサポートされているため、マップへの変更はセットに反映され、その逆も同様です。

于 2016-02-08T17:44:59.603 に答える