3

Set の for-each-loops が、反復子が要素を常に同じ順序で返すという事実に依存する必要があるコードがあります。

for(ParameterObject parameter : parameters) { /* ... */ }

によって返される反復子HashSetがこのプロパティを持つことは保証されていませんが、 の反復子がこのプロパティを持つことが文書化されていLinkedHashSetます。したがって、私のコードは aを使用しLinkedHashSet、すべて正常に動作します。

ただし、渡されたセットが要件に準拠していることをコードに確認できるかどうか疑問に思っています。これは不可能であるかのように見えます (上の直接テストを除くLinkedHashSet)。LinkedHashSetテストできるインターフェイスが実装されておらず、テストできるインターフェイスも実装されていませんLinkedHashSet.iterator()OrderConsistentCollectionやのようなインターフェースがあればいいですねOrderConsistentIterator

(ここでこのプロパティが必要です)。

4

2 に答える 2

3

それを確認する方法はありませんが、そのプロパティを持つコレクションにセットをコピーするだけで確認できます。ALinkedHashSetでうまくいきますが、反復だけが必要な場合は、ArrayListおそらく A の方が適しています。

List<Foo> parameters = new ArrayList<>(parametersSet);

parameters常に同じ順序でイテレータを返すようになりました。

そうは言っても、Evgeniy Dorofeev の提案はおそらく問題ないでしょう。これは、特定の順序を保証しないセットでさえ、通常は安定した順序を持っていることを指摘しています(保証されていなくても)。HashSetたとえば、そのように動作します。安定した順序を持たないようにするには、実際にはかなりファンキーなセットを用意するか、積極的なランダム化対策を講じる必要があります。

HashSetの順序は保証されていませんが、要素のハッシュ コードと挿入された順序に依存します。オブジェクトのハッシュコードがObject.hashCode(). 複雑な意味を持つ順序を指定してから、それが変更される可能性があると言うのではなく、彼らはただ保証はないと言いました. しかし、これらは順序付けのための 2 つの要素であり、セットが変更されていない場合、これら 2 つの要素は反復間で安定します。

于 2013-01-04T15:33:46.303 に答える
2

「HashSet.iterator は特定の順序で返されない」とは、iterator によって返される要素が List や LinkedHashSet のように並べ替えられたり順序付けられたりしていないことを意味します。ただし、HashSet.iterator は常に同じ順序で要素を返しますが、HashSet は同じです。

HashSet イテレータは実際には予測可能です。これを参照してください

    HashSet set = new HashSet();
    set.add(9);
    set.add(2);
    set.add(5);
    set.add(1);
    System.out.println(set);

出力は 1、2、5、9 になると予測できます。要素が hashCode でソートされているためです。

于 2013-01-04T15:22:26.220 に答える