76

.NET 3.5 で導入されたHashSetコレクションは、を使用して反復したときに挿入順序を保持しforeachますか?

ドキュメントには、コレクションはソートされていないと記載されていますが、挿入順序については何も述べられていません。プレリリースの BCLブログ エントリには、順序付けされていないと記載されていますが、この記事では、挿入順序を維持するように設計されていると記載されています。私の限られたテストでは、順序が保持されていることが示唆されていますが、それは偶然の一致である可能性があります。

4

6 に答える 6

87

この HashSet MSDN ページには、具体的に次のように記載されています。

セットは、重複する要素を含まず、要素が特定の順序になっていないコレクションです。

于 2009-03-18T08:03:12.557 に答える
46

順序を維持すると主張する記事は、まったく間違っていると思います。単純なテストでは、内部構造により挿入順序が維持される場合がありますが、保証されておらず、常にそのように機能するとは限りません。反例を考えてみます。

編集:反例は次のとおりです。

using System;
using System.Collections.Generic;

class Test
{
    static void Main()
    {
        var set = new HashSet<int>();

        set.Add(1);
        set.Add(2);
        set.Add(3);
        set.Remove(2);
        set.Add(4);


        foreach (int x in set)
        {
            Console.WriteLine(x);
        }
    }
}

これは、3 が 4 の前に挿入されているにもかかわらず、1、4、3 を出力します。

アイテムを削除しないと、挿入順序が保持される可能性があります。よくわかりませんが、まったく驚かないでしょう。ただし、それに頼るのは非常に悪い考えだと思います。

  • そのように動作するように文書化されておらず、ドキュメントにはソートされていないと明示的に記載されています。
  • 私は内部構造やソース コード (明らかに持っていません) を見ていません。
  • 実装は、フレームワークのバージョン間で非常に簡単に変更できます。これに依存することは、変更されていない実装に依存するようなものです..NET 1.1の時代に何人かの人々がそれを行い、.NET 2.0で実装変更さstring.GetHashCodeれたときにやけどを負いました.
于 2009-03-18T07:54:05.247 に答える
7

ドキュメントには次のように記載されています。

HashSet<(Of <(T>)>) コレクションはソートされておらず、重複する要素を含めることはできません。アプリケーションのパフォーマンスよりも順序または要素の重複が重要な場合は、 List<(Of <(T>)>) クラスを Sort メソッドと共に使用することを検討してください。

したがって、現在の実装で要素の順序が実際に保持されているかどうかは問題ではありません。そのように文書化されていないためです。枠組み)。

実装の詳細ではなく、文書化されたコントラクトに対してプログラミングする必要があります。

于 2009-03-18T08:04:17.577 に答える
3

特にSortedSet<T>.NET4にはコレクションがあります。

これにより並べ替えが可能になりますが、挿入順の並べ替えになる可能性は低くなります。カスタムを使用できるので、IComparer理論的にはこれで何でもできます。

于 2012-03-19T19:43:29.347 に答える
2

HashSet.AddIfNotPresentのソース コードを読むと、削除がないと仮定して挿入順序が保持されていることがわかります。

したがってnew HashSet<string> { "Tom", "Dick", "Harry" }、順序は保持されますが、ディックを削除してリックを追加すると、順序は ["Tom", "Rick", "Harry"] になります。

于 2016-04-26T15:52:27.220 に答える
2

いいえ、ハッシュ セットは挿入順序を保持しません。少なくとも予想通りではありません。LinkedHashSet (Java)、または同等のものを使用できます。LinkedHashSet は順序を保持します。

順序が必要な場合は、そもそもセットを使用するべきではありません...例外的な場合を除いて、順序付けされた要素用に作成されていません。

編集: 私が説教しているように聞こえます :-/ ごめんなさい。

于 2009-03-18T09:11:19.397 に答える