1. ホーム
  2. java

[解決済み] なぜJava MapはCollectionを拡張しないのですか?

2022-04-26 17:23:41

質問

ということに驚きました。 Map<?,?>Collection<?> .

と宣言されれば、LOTの意味があるかと。

public interface Map<K,V> extends Collection<Map.Entry<K,V>>

結局のところ Map<K,V> の集合体です。 Map.Entry<K,V> ということでしょうか?

では、そのように実装されていないのには、何か理由があるのでしょうか?


Cletusが最も権威ある回答をしてくれたことに感謝します。 Map<K,V> として Set<Map.Entries<K,V>> (経由 entrySet() のように、そのインターフェイスを拡張するだけではありません。

もし MapCollection は、どのような要素なのでしょうか?唯一の合理的な答えは、「キーと値のペア」です。

その通りです。 interface Map<K,V> extends Set<Map.Entry<K,V>> があれば最高です。

が、これは非常に限定的な(そして特に有用ではない)ものを提供します。 Map を抽象化したものです。

しかし、もしそうだとしたら、なぜ entrySet インターフェイスで指定されているのでしょうか?それは何らかの形で役に立つに違いありません(その立場を主張するのは簡単だと思います!)。

あるキーがどのような値に対応するかを尋ねることはできませんし、どのような値に対応するかを知らずに、あるキーのエントリーを削除することもできません。

にそれがすべてだとは言いません。 Map ! することができ すべき は、他のすべてのメソッド (ただし entrySet これはもう冗長です。)

解決方法は?

からの Java Collections API設計に関するFAQ :

<ブロッククオート

なぜMapはCollectionを拡張しないのか?

これはデザインによるものです。私たちは マッピングはコレクションではありませんし コレクションはマッピングではありません。したがって を拡張することは、ほとんど意味がありません。 コレクション・インターフェース(またはその逆 のようになります。)

MapがCollectionである場合、そのCollectionは何であるか? 要素になります。唯一の合理的な答えは は、キーと値のペアです。 非常に限定的な(そして 特に有用な)マップの抽象化です。 与えられたキーがどのような値であるかを尋ねることはできません。 へのマッピング、エントリの削除はできません。 を知ることなく、与えられたキーの という値があります。

コレクションは Mapですが、これには疑問が残ります。 キーは何か?本当に 満足な答えがなく、無理に は不自然なインタフェースになる。

マップはコレクションと見なすことができます。 キー、値、またはペア)であり、この事実が は、3つの "コレクション ビュー操作" マップに対する操作(keySet, entrySet、values)の3つです。しかし 原理的には、リストを インデックスを要素にマッピングするMap。 これは、以下のような厄介な性質があります。 リストから要素を削除する は、すべての を削除します。 これがマップビューの理由です。 の操作を行うことができます。

更新してください。 引用文がほとんどの質問に答えていると思います。エントリーのコレクションは特に有用な抽象化ではないという部分を強調する価値があります。例えば

Set<Map.Entry<String,String>>

は許可することになる。

set.add(entry("hello", "world"));
set.add(entry("hello", "world 2"));

(を想定しています。 entry() を作成するメソッドです。 Map.Entry のインスタンス)

Map は一意なキーを必要とするので、これはこれに違反することになります。あるいは、一意のキーを Set のエントリの場合、それは実際には Set 一般的な意味での それは Set に、さらに制限を加えたものです。

と言えるかもしれません。 equals() / hashCode() の関係 Map.Entry は純粋にキーだけでしたが、それにも問題があります。もっと重要なのは、それが本当に付加価値を生むのか、ということです。このような抽象化は、コーナーケースを見始めると、破綻していることに気づくかもしれません。

注目すべきは HashSet は、実際には HashMap であり、その逆ではありません。これは純粋に実装の詳細ですが、それにしても興味深いことです。

の主な理由は entrySet() が存在するのは、キーをトラバースしてそのキーをルックアップする必要がないように、トラバーサルを簡略化するためです。という一応の証拠と捉えてはいけません。 Map であるべきです。 Set のエントリーです(イミフ)。