2017-12-01 4 views
-1

私はHashSetsが本質的に順序付けられていないことを知っていますが、コレクションはおそらくハッシュバケットに基づいて何らかの順序で格納されています。 First拡張メソッドは、最初の要素を取得し、それを呼び出し側に配信します。私の質問は次のとおりです。.NETプラットフォームはいくつかの実装が可能な標準であるため、拡張メソッド(System.Linq名前空間から)は、HashSetsのような順序付けられていないコレクションに対して常に同じ要素を返す必要がありますコレクションの内容は変更されませんか?私はメモリ最適化のようなものを想像しています。もしそれがFirstの標準の要件の1つでないならば、プラットフォームの異なる実装で異なる動作を引き起こす可能性があります。Linq拡張機能は、最初にHashSetの後続の呼び出しで同じ要素を一貫して返す必要がありますか?

'Firstは、どのデバイスに関係なく、現在も将来も動作することができますか?'私が求めていることの要点になるだろう。

+2

予測可能である)のためと思われます15歳でAndroid 12.3 - 同じ正確なHashSetのために - あなたは今まで知っていることはありません。ちょうどHashSetの実装が同じであることを願っています。 –

+1

この回答は、それに頼ることは非常に悪い考えであると説明しています。https://stackoverflow.com/a/657289/2651069 –

+0

私はなぜこれに頼る必要があるのでしょうか? – Evk

答えて

1

First()で呼び出したクラスのGetEnumerator()呼び出しから返された最初の要素を返すことができます。

ただし、順序付けされていないコレクションの場合と同様に、HashSet.GetEnumerator()から返された最初のアイテムの未定義の動作は、変更されていないコレクションへの複数の呼び出しで常に同じアイテムになります。それは今日同じものを返すかもしれませんが、それは将来のバージョンでそのように残る必要があると述べる契約はありません。 HashSetのに数の各挿入時に最初に()を使用して*すべての挿入後、すべてのHashSetのは、同じデータをすべてまず

印刷を(含まれている別のHashSetの にそれぞれを覚えている複数のHashSetの *を作成 *:

+0

私は理解します。それは残念です...私のアルゴリズム全体がちょうど崩壊しました...私はリストを使用しなければならず、代わりにContainsを使用する必要があります。ありがとう。 – FinnTheHuman

0

チェック)の

using System; 
using System.Collections.Generic; 
using System.Collections; 
using System.Linq; 

public class Program 
{ 
    static IEnumerable<int> Range(int min, int max) 
    { 
     for (int i = min; i <= max; i++) 
      yield return i; 
    } 

    public static void Main() 
    { 
     var firsts = new HashSet<int>(); 
     for (int i = 0; i < 10; i++) 
     { 
      Console.WriteLine("Run: " + i.ToString()); 
      var h = new HashSet<int>(); 
      foreach (var num in Range(-1000, +1000).OrderBy(o => Guid.NewGuid()).ToList()) 
      { 
       h.Add(num); 
       if (h.Count == 1) 
        Console.WriteLine("first value inserted: " + num.ToString()); 
       firsts.Add(h.First()); 
      } 

      Console.WriteLine("All firsts: " + string.Join(",", firsts)); 
      firsts.Clear(); 
     } 

     Console.ReadLine(); 
    } 
} 

観察:

  • 各HashSetの自体にのみ1を生成しますすべて2001年のインサート上に第一-値
  • すべてHashSetの異なる1次回を(生成) - 値は、彼らが他の最初のint

Run: 0 first value inserted: 507 All firsts: 507 Run: 1 first value inserted: 511 All firsts: 511 Run: 2 first value inserted: -600 All firsts: -600 Run: 3 first value inserted: -624 All firsts: -624 Run: 4 first value inserted: -367 All firsts: -367 Run: 5 first value inserted: -110 All firsts: -110 Run: 6 first value inserted: 983 All firsts: 983 ... etc ...

  • HashSetのインスタンスを開始した場合には、同じファーストを(持っているようです)
  • ハッシュセットに入れられる最初の項目
  • 異なっているように見える異なるHashSetは異なるように見える最初の値が異なる場合は/最初の値が異なる場合
  • 少なくともWindowsと現在のコンパイラの下
  • は、それはHashSetの1次回()あなたはWin10上で、今日HashSetの上で()1次回をキャッシュして(1次回にそれを比較する場合を除き、それは
+0

はい 'HashSet'は私のマシンで' First'の戻り値が40分を少し越えているようです。しかし、私の問題は、それが.NET標準の契約であるかどうかを知ることです。同様に、標準では、長い整数は64ビットでなければなりません。あなたは確かに、どんなプラットフォームであっても、いつでも(長い変更が標準に加えられない限り)、long intは64ビットを持つでしょう。 – FinnTheHuman

関連する問題