web-dev-qa-db-ja.com

Javaで、(ソートされていない)SetがIterableを実装しているのに、SortedMapが実装していないのはなぜですか?

この質問には2つの側面があり、個別の質問として質問するには密接に関連していると感じました。

  1. なぜSortedMap実装しないIterable<Map.Entry<K,V>>

マップ内のすべてのキーと値のペアに対してアクションを実行する必要がある場合は、entrySet()を反復処理する方法のようです。それでは、SortedMapに直接iterator()メソッドを提供しないのはなぜですか? HashMapでの反復順序の不整合が心配でない限り。これは私を導きます:

  1. Iterableの実装は、安定した順序付けを意味しますか?

順序付けられたコレクション(List、SortedMap、SortedSet)を反復処理することは、equals()(注1を参照)を確実に実装し、毎回同じ結果を生成する必要がある他のことを実行する優れた方法です。ソートされていないセットまたはマップを繰り返し処理すると、複数回呼び出すと順序が異なる可能性があるため、これらの目的には適していません。特にHashSetまたはHashMapを比較する場合-それらの2つは同じオブジェクトを含むことができますが、それらの反復子の順序は異なります。

これらの質問には2つの側面があると思います。

  1. これらの設計決定の歴史的な理由は何ですか?

  2. 今日それをもう一度行う場合、これらの質問に対する正しい答えはありますか?多分OrderedIterableIterableを拡張して順序を保証する必要がありますか?

メモ:

  1. 元々、hashCode()を実装するには信頼できる順序が必要であると示唆していましたが、すべてのハッシュコードを合計すると、ハッシュアルゴリズムが可換であれば、信頼できる順序は必要ないことがわかります。加算は一般的にhashCodesに使用され、それは可換です:a + b = b + aおよびB。オーバーフローがあっても、加算は可換であるため、a + Integer.MAX_VALUE = Integer.MAX_VALUE + aになります。 equals()を実装して、一方の最初の項目をもう一方の最初の項目と比較できるように、信頼できる順序付けが必要です。

P.S。

この質問は、インターフェイスIterableSetSortedSetMap、およびSortedMapに関するものです。例として他のインターフェースを取り上げることは問題ありませんが、Collectionインターフェースがこの質問に関連するとは思いません。それは風変わりで、注意散漫になる可能性があります。

7
GlenPeterson

狭義の技術的な観点から見ると、SetIterableを実装していると言いますが、SortedMapはそうではありませんが、質問するのはあまり役に立ちません。もっと役立つ質問は、両方のクラスofferIterableインターフェースかどうか、そして確かに両方がそうであるかどうかです。

ご存じのとおり、インターフェースを提供する方法は3つあります。

  1. implementsキーワードを使用して明示的に実装する。
  2. 問題のインターフェースを拡張するインターフェースを実装することによって。
  3. 問題のインターフェイスを返す関数を公開する。

Setは次のように宣言されます:_public interface Set<E> extends Collection<E> {..._つまり、ご覧のとおり、SetIterableを直接実装せず、Collectionを実装することによって間接的にのみ実装し、Iterableを拡張します。

ここで、SortedMapwouldは、IterableSetを実装していた場合と同様に、間接的にCollectionも間接的に実装しますが、それも行いません。代わりに、entrySet()関数を公開します。この関数は、Collectionを拡張するIterableを返します。

したがって、どちらの場合でも、希望するIterableを使用できます。

SetIterableを(間接的に)実装する理由についての狭い技術的な質問を主張したいが、SortedMapが代わりに関数を介してそれを提供する場合、答えはJava言語ランタイムの作成他のインターフェースを拡張するインターフェースを広範囲に使用することを控えるというずっと前の決定です。そのため、_Map<K,V>_は_Collection<Map.Entry<K,V>>_を拡張せず、代わりにentrySet()メソッドを提供します。

彼らは逆のことをしたかもしれません、そして実際のところ、C#言語ランタイムの設計者は逆に行くことを選んだので、_IDictionary<K,V>_は_ICollection<KeyValuePair<K,V>>_を拡張します。

私は両方の方法で実験しましたが、どちらがより良いかについての決定的な結論にはまだ至っていません。それらは単に、同じことを達成するための2つの異なる方法のように見えます。

Iteratorの実装は、あなたが理解しているように見えるので、安定した順序付けを意味しません(したがって、その点で質問がどこにあるのか私には明確ではありません。)ソートされていないマップを反復する場合があります。アイテムの順序は次のようになります。また、要素をマップに挿入して繰り返すことができます。その場合、アイテムの順序は前回とまったく異なる場合があります。 (1つのアイテムだけが異なるのではなく、すべてのアイテムが再配置されているように見えることがあります。)

シグニチャーはOrderedIterableと同一であるため、Iterableインターフェースは必要ありません。 (そして、Java Set以外にCollectionを紹介する人たちにJava ====の選択から始めさせないでください。)あなたは単にOrderedMap.entrySet()を呼び出すことができます。 orderedセット。これは、そのセットのIteratorが常に順序どおりに項目を生成することを意味します。

12
Mike Nakis