Java Map が Collection を拡張しないのはなぜですか? 質問する

Java Map が Collection を拡張しないのはなぜですか? 質問する

Map<?,?>が ではないという事実に驚きましたCollection<?>

次のように宣言すれば、非常に意味があると思いました。

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

結局のところ、aMap<K,V>Map.Entry<K,V>、 そうじゃない?

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


非常に信頼できる回答をしてくれた Cletus に感謝します。しかし、 を( 経由で)Map<K,V>として表示できるのであれば、代わりにそのインターフェースを拡張しないのはなぜなのか、まだ疑問に思っています。Set<Map.Entries<K,V>>entrySet()

Mapが である場合Collection、要素は何ですか? 唯一の合理的な答えは「キーと値のペア」です。

まさに、interface Map<K,V> extends Set<Map.Entry<K,V>>素晴らしいですね!

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

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

特定のキーがどの値にマップされているかを問い合わせることはできません。また、特定のキーがどの値にマップされているかを知らずにそのキーのエントリを削除することもできません。

それがすべてだと言っているのではありませんMapすべき他のすべてのメソッドを保持してください (entrySet現在は冗長になっている を除く)。

ベストアンサー1

からJava コレクション API 設計に関する FAQ:

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

これは設計によるものです。マッピングはコレクションではなく、コレクションはマッピングではないと考えています。したがって、Map が Collection インターフェースを拡張する (またはその逆) ことはあまり意味がありません。

マップがコレクションである場合、要素は何でしょうか? 唯一の妥当な答えは「キーと値のペア」ですが、これは非常に限定された (特に有用ではない) マップの抽象化を提供します。特定のキーがどの値にマップされているかを尋ねることはできませんし、マップされている値がわからないまま特定のキーのエントリを削除することもできません。

Collection は Map を拡張するように作成できますが、キーとは何でしょうか? という疑問が生じます。本当に満足のいく答えはなく、無理やり答えようとすると不自然なインターフェースになります。

マップはコレクション (キー、値、またはペア) として表示できます。この事実は、マップの 3 つの「コレクション ビュー操作」(keySet、entrySet、および値) に反映されています。原則として、リストをインデックスを要素にマッピングするマップとして表示することは可能ですが、これには、リストから要素を削除すると、削除された要素の前のすべての要素に関連付けられたキーが変更されるという厄介な特性があります。そのため、リストにはマップ ビュー操作がありません。

アップデート:この引用文はほとんどの質問に答えていると思います。エントリのコレクションは特に有用な抽象化ではないという部分を強調しておく価値があります。たとえば、次のようになります。

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()という一見したところの証拠として受け取らないでください(私見)。MapSet

おすすめ記事