2013-08-11T23:47:33の更新内容

programming/netfx/collections/2_generic_6_hashset_sortedset/index.wiki.txt

current previous
11,20 11,9
 
#googleadunit(banner)
#googleadunit(banner)
 

        

        
 
*HashSetとSortedSet [#HashSetSortedSet]
*HashSetとSortedSet [#HashSetSortedSet]
~
&msdn(netfx,type,System.Collections.Generic.HashSet`1){System.Collections.Generic.HashSetクラス};と&msdn(netfx,type,System.Collections.Generic.SortedSet`1){System.Collections.Generic.SortedSetクラス};は、数学における集合の概念を表すコレクションクラスです。 HashSetは.NET Framework 3.5 SP1、SortedSetは.NET Framework 4より提供されています。
&msdn(netfx,type,System.Collections.Generic.HashSet`1){System.Collections.Generic.HashSetクラス};と&msdn(netfx,type,System.Collections.Generic.SortedSet`1){System.Collections.Generic.SortedSetクラス};は、数学における集合の概念を表すコレクションクラスです。 HashSetは.NET Framework 3.5 SP1、SortedSetは.NET Framework 4より提供されています。 HashSetクラス・SortedSetクラスを使うことで、コレクション同士の包含関係を調べたり集合同士の和や積を求めることが出来ます。 また、SortedSetクラスは、HashSetクラスに並べ替えの機能を追加したクラスで、要素を追加したり列挙したりする際に自動的にソートされます。 System.Collections名前空間ではHashSetクラス・SortedSetクラスに相当するクラス、集合の概念を表すコレクションクラスは提供されていません。
 

        

        
~
HashSetクラス・SortedSetクラスを使うことで、一方のコレクションが他方のコレクションと重複する部分を持つか、あるいは完全に異なるか、他方を内包するか、といったコレクション同士の包含関係を調べることができます。 また、コレクション同士の和(OR)を求めて二つのコレクションをマージしたり、積(AND)を求めて共通する要素だけを残したりすることができます。
**基本操作
+

          
+
HashSet・SortedSetでは、要素は重複することなく格納されます。 Listなどとは異なり既に追加されている要素を追加しようとしても重複して格納されることなく、常に単一の要素として扱われます。 そのため、HashSet・SortedSetはキーだけを扱う一種のDictionaryのようなコレクションと見ることもできます。
+

          
+
またSortedSetクラスは、名前のとおりHashSetクラスに並べ替えの機能を追加したクラスで、要素を追加したり列挙したりする際には自動的にソートされます。
+

          
+
.NET Framework 4以降ではHashSet・SortedSetはともに&msdn(netfx,type,System.Collections.Generic.ISet`1){ISet<T>インターフェイス};を実装しています。 .NET Framework 3.5ではISet<T>は存在せず、そのためHashSetもISet<T>を実装していないので注意してください。
+

          
+
System.Collections名前空間ではHashSetクラス・SortedSetクラスに相当するクラス、集合の概念を表すコレクションクラスは提供されていません。
+

          
+

          
+
*基本操作
 
HashSetクラス・SortedSetクラスともに、Listや他のコレクションクラスと共通するAdd, Remove, Contains, Clearなどのメソッドが用意されていて、単なるコレクションとして使う場合は他のコレクションクラスと何ら違いはありません。 また、SortedSetでは並べ替えが行われる以外、動作と結果も同じです。
HashSetクラス・SortedSetクラスともに、Listや他のコレクションクラスと共通するAdd, Remove, Contains, Clearなどのメソッドが用意されていて、単なるコレクションとして使う場合は他のコレクションクラスと何ら違いはありません。 また、SortedSetでは並べ替えが行われる以外、動作と結果も同じです。
 

        

        
 
#tabpage(codelang=cs,HashSet/C#)
#tabpage(codelang=cs,HashSet/C#)
189,163 178,15
 
}}
}}
 
#tabpage-end
#tabpage-end
 

        

        
~
一方、HashSet・SortedSetでは同じ要素を複数回格納しようとしても重複して格納されることはなく、常に1つだけ格納されます。 この点はDictionaryのキーと似た動作と言えますが、重複していても例外がスローされることはありません。 同じ要素が重複することはありませんが、HashSetでは格納した時の順序は維持されます。
**集合演算
~

          
HashSetクラス・SortedSetクラスには集合演算を行うメソッドとして次のメソッドが用意されています。 いずれも引数としてIEnumerable<T>を取り、戻り値は無く(void)、メソッドを実行した結果はインスタンス自身に反映されます。
+
#tabpage(codelang=cs,HashSet/C#)
+
#code{{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    HashSet<int> s = new HashSet<int>();
+

          
+
    // 同じ要素を複数回追加
+
    s.Add(3);
+
    s.Add(3);
+
    s.Add(3);
+

          
+
    s.Add(1);
+
    s.Add(1);
+

          
+
    s.Add(2);
+

          
+
    Print(s);
+
  }
+

          
+
  static void Print(HashSet<int> s)
+
  {
+
    foreach (int e in s)
+
    {
+
      Console.Write("{0}, ", e);
+
    }
+

          
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(codelang=cs,SortedSet/C#)
+
#code{{
+
using System;
+
using System.Collections.Generic;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    SortedSet<int> s = new SortedSet<int>();
+

          
+
    // 同じ要素を複数回追加
+
    s.Add(3);
+
    s.Add(3);
+
    s.Add(3);
+

          
+
    s.Add(1);
+
    s.Add(1);
+

          
+
    s.Add(2);
+

          
+
    Print(s);
+
  }
+

          
+
  static void Print(SortedSet<int> s)
+
  {
+
    foreach (int e in s)
+
    {
+
      Console.Write("{0}, ", e);
+
    }
+

          
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(codelang=vb,HashSet/VB)
+
#code{{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim s As New HashSet(Of Integer)()
+

          
+
    ' 同じ要素を複数回追加
+
    s.Add(3)
+
    s.Add(3)
+
    s.Add(3)
+

          
+
    s.Add(1)
+
    s.Add(1)
+

          
+
    s.Add(2)
+

          
+
    Print(s)
+
  End Sub
+

          
+
  Shared Sub Print(ByVal s As HashSet(Of Integer))
+
    For Each e As Integer In s
+
      Console.Write("{0}, ", e)
+
    Next
+

          
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage(codelang=vb,SortedSet/VB)
+
#code{{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim s As New SortedSet(Of Integer)()
+

          
+
    ' 同じ要素を複数回追加
+
    s.Add(3)
+
    s.Add(3)
+
    s.Add(3)
+

          
+
    s.Add(1)
+
    s.Add(1)
+

          
+
    s.Add(2)
+

          
+
    Print(s)
+
  End Sub
+

          
+
  Shared Sub Print(ByVal s As SortedSet(Of Integer))
+
    For Each e As Integer In s
+
      Console.Write("{0}, ", e)
+
    Next
+

          
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#tabpage(実行結果/HashSet)
+
#prompt{{
+
3, 1, 2, 
+
}}
+
#tabpage(実行結果/SortedSet)
+
#prompt{{
+
1, 2, 3, 
+
}}
+
#tabpage-end
+

          
+

          
+

          
+
*集合演算
+
HashSetクラス・SortedSetクラスには集合演算を行うメソッドとして次のメソッドが用意されています。 いずれも引数としてIEnumerable<T>を取り、戻り値はありません(void)。 したがって、これらのメソッドでは引数に指定された配列やコレクションなどとの演算結果をインスタンス自身に反映します。
 

        

        
 
|*集合演算を行うメソッド
|*集合演算を行うメソッド
 
|~メソッド|~動作|h
|~メソッド|~動作|h
~
|&msdn(netfx,member,System.Collections.Generic.HashSet`1.IntersectWith){HashSet.IntersectWith};&br;&msdn(netfx,member,System.Collections.Generic.SortedSet`1.IntersectWith){SortedSet.IntersectWith};|現在の集合と引数で指定されたIEnumerable<T>との積集合を求める&br;(引数の集合と''共通する要素のみを残す'')|
|&msdn(netfx,member,System.Collections.Generic.HashSet`1.IntersectWith){HashSet.IntersectWith};&br;&msdn(netfx,member,System.Collections.Generic.SortedSet`1.IntersectWith){SortedSet.IntersectWith};|現在の集合と引数で指定されたIEnumerable<T>との積集合を求める&br;(引数の集合と共通する要素のみを残す)|
~
|&msdn(netfx,member,System.Collections.Generic.HashSet`1.UnionWith){HashSet.UnionWith};&br;&msdn(netfx,member,System.Collections.Generic.SortedSet`1.UnionWith){SortedSet.UnionWith};|現在の集合と引数で指定されたIEnumerable<T>との和集合を求める&br;(引数の集合の要素を''マージする'')|
|&msdn(netfx,member,System.Collections.Generic.HashSet`1.UnionWith){HashSet.UnionWith};&br;&msdn(netfx,member,System.Collections.Generic.SortedSet`1.UnionWith){SortedSet.UnionWith};|現在の集合と引数で指定されたIEnumerable<T>との和集合を求める&br;(引数の集合の要素をマージする)|
~
|&msdn(netfx,member,System.Collections.Generic.HashSet`1.ExceptWith){HashSet.ExceptWith};&br;&msdn(netfx,member,System.Collections.Generic.SortedSet`1.ExceptWith){SortedSet.ExceptWith};|現在の集合と引数で指定されたIEnumerable<T>との差集合を求める&br;(引数の集合の要素を''除外する'')|
|&msdn(netfx,member,System.Collections.Generic.HashSet`1.ExceptWith){HashSet.ExceptWith};&br;&msdn(netfx,member,System.Collections.Generic.SortedSet`1.ExceptWith){SortedSet.ExceptWith};|現在の集合と引数で指定されたIEnumerable<T>との差集合を求める&br;(引数の集合の要素を削除する)|
~
|&msdn(netfx,member,System.Collections.Generic.HashSet`1.SymmetricExceptWith){HashSet.SymmetricExceptWith};&br;&msdn(netfx,member,System.Collections.Generic.SortedSet`1.SymmetricExceptWith){SortedSet.SymmetricExceptWith};|現在の集合と引数で指定されたIEnumerable<T>との対称差を求める&br;(引数の集合と''共通する要素のみを除外する'')|
|&msdn(netfx,member,System.Collections.Generic.HashSet`1.SymmetricExceptWith){HashSet.SymmetricExceptWith};&br;&msdn(netfx,member,System.Collections.Generic.SortedSet`1.SymmetricExceptWith){SortedSet.SymmetricExceptWith};|現在の集合と引数で指定されたIEnumerable<T>との対称差を求める&br;(引数の集合と共通する要素を削除する)|
 

        

        
 
以下は、上記の集合演算を使った例です。
以下は、上記の集合演算を使った例です。
 

        

        
571,104 412,7
 

        

        
 
&image(set_operation_intersectwith.png,nopopup,IntersectWithの結果); &image(set_operation_unionwith.png,nopopup,UnionWithの結果); &image(set_operation_exceptwith.png,nopopup,ExceptWithの結果); &image(set_operation_symmetricexceptwith.png,nopopup,SymmetricExceptWithの結果);
&image(set_operation_intersectwith.png,nopopup,IntersectWithの結果); &image(set_operation_unionwith.png,nopopup,UnionWithの結果); &image(set_operation_exceptwith.png,nopopup,ExceptWithの結果); &image(set_operation_symmetricexceptwith.png,nopopup,SymmetricExceptWithの結果);
 

        

        
~
**LINQ
**包含関係の検証
+
LINQの拡張メソッドを使うことでも集合演算を行うことはできます。 それぞれ対応するメソッドは次のとおりです。
+

          
+
|*対応するLINQの拡張メソッド
+
|~演算|~HashSet/SortedSetのメソッド|~LINQの拡張メソッド|h
+
|~積集合|IntersectWith|&msdn(netfx,member,System.Linq.Enumerable.Intersect){Intersect};|
+
|~和集合|UnionWith|&msdn(netfx,member,System.Linq.Enumerable.Union){Union};|
+
|~差集合|ExceptWith|&msdn(netfx,member,System.Linq.Enumerable.Except){Except};|
+

          
+
以下の例はこれらのメソッドを使ってHashSet・SortedSetと同様の集合演算を行う例です。 LINQではSymmetricExceptWithに相当する対象差を求めるメソッドは提供されませんが、以下の例のように差集合同士の和集合を求めることで対象差を求めることができます。
+

          
+
#tabpage(codelang=cs,container-title=LINQの拡張メソッドを使って集合演算を行う例)
+
#code{{
+
using System;
+
using System.Collections.Generic;
+
using System.Linq;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    int[] set1 = new int[] {6, 2, 0, 4, 8};
+
    int[] set2 = new int[] {3, 1, 2, 0, 4};
+

          
+
    // 積集合を求める
+
    Print(set1.Intersect(set2));
+

          
+
    // 和集合を求める
+
    Print(set1.Union(set2));
+

          
+
    // 差集合を求める
+
    Print(set1.Except(set2));
+

          
+
    // 対象差を求める
+
    var diffset1 = set1.Except(set2);
+
    var diffset2 = set2.Except(set1);
+

          
+
    Print(diffset1.Union(diffset2));
+
  }
+

          
+
  static void Print(IEnumerable<int> s)
+
  {
+
    foreach (int e in s)
+
    {
+
      Console.Write("{0}, ", e);
+
    }
+

          
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.Collections.Generic
+
Imports System.Linq
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim set1() As Integer = New Integer() {6, 2, 0, 4, 8}
+
    Dim set2() As Integer = New Integer() {3, 1, 2, 0, 4}
+

          
+
    ' 積集合を求める
+
    Print(set1.Intersect(set2))
+

          
+
    ' 和集合を求める
+
    Print(set1.Union(set2))
+

          
+
    ' 差集合を求める
+
    Print(set1.Except(set2))
+

          
+
    ' 対象差を求める
+
    Dim diffset1 As IEnumerable(Of Integer) = set1.Except(set2)
+
    Dim diffset2 As IEnumerable(Of Integer) = set2.Except(set1)
+

          
+
    Print(diffset1.Union(diffset2))
+
  End Sub
+

          
+
  Shared Sub Print(ByVal s As IEnumerable(Of Integer))
+
    For Each e As Integer In s
+
      Console.Write("{0}, ", e)
+
    Next
+

          
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
2, 0, 4, 
+
6, 2, 0, 4, 8, 3, 1, 
+
6, 8, 
+
6, 8, 3, 1, 
+
}}
+

          
+

          
+
*包含関係の検証
 
HashSetクラス・SortedSetクラスには包含関係の検証を行うメソッドとして次のメソッドが用意されています。 いずれも引数としてIEnumerable<T>を取り、戻り値は真偽値(boolean)です。 なお、要素の並びが異なっていても包含関係には影響しません。
HashSetクラス・SortedSetクラスには包含関係の検証を行うメソッドとして次のメソッドが用意されています。 いずれも引数としてIEnumerable<T>を取り、戻り値は真偽値(boolean)です。 なお、要素の並びが異なっていても包含関係には影響しません。
 

        

        
 
|*包含関係の検証を行うメソッド
|*包含関係の検証を行うメソッド
910,8 654,7
 

        

        
 
SortedSetで並べ替えが行われる以外は、結果は同じです。
SortedSetで並べ替えが行われる以外は、結果は同じです。
 

        

        
~

          
**等価性比較のカスタマイズ
+
*等価性比較のカスタマイズ [#EqualityComparison]
 
HashSetのコンストラクタで適切なIEqualityComparer<T>インターフェイスを指定することで、要素の等価性比較時の動作をカスタマイズ出来ます。 例えば、比較の際に大文字小文字を無視するようにするといったことが出来ます。 以下は、StringComparerクラスを使って、大文字小文字を無視するHashSetを作成する例です。
HashSetのコンストラクタで適切なIEqualityComparer<T>インターフェイスを指定することで、要素の等価性比較時の動作をカスタマイズ出来ます。 例えば、比較の際に大文字小文字を無視するようにするといったことが出来ます。 以下は、StringComparerクラスを使って、大文字小文字を無視するHashSetを作成する例です。
 

        

        
 
#tabpage(codelang=cs)
#tabpage(codelang=cs)
957,148 700,9
 
True
True
 
}}
}}
 

        

        
~
IEqualityComparer<T>インターフェイスや実装例については[[programming/netfx/comparison/1_equation]]を参照してください。 なお、SortedSetでは等価性比較だけではなく大小関係の比較も行うため、IEqualityComparer<T>インターフェイスではなく[[IComparer<T>インターフェイス>#Comparison]]を要求します。
なお、SortedSetでは等価性比較だけではなく大小関係の比較も行うため、IEqualityComparer<T>インターフェイスではなくIComparer<T>インターフェイスを要求します。
+

          
+

          
+
**HashSetでKeyValuePairを扱う
+
等価性比較のカスタマイズ例として、HashSetでKeyValuePairを扱う例をみてみます。 次の例では、KeyValuePairからKeyの値を取得して比較を行うクラスKeyValuePairEqualityComparerを作成し、それをHashSetのコンストラクタに渡しています。 これによりKeyValuePair同士の比較ができるようになり、HashSetでKeyValuePairを扱うことができるようになります。
+

          
+
#tabpage(codelang=cs)
+
#code{{
+
using System;
+
using System.Collections.Generic;
+

          
+
// KeyValuePair<string, int>の等価性比較を行うIEqualityComparer<T>
+
class KeyValuePairEqualityComparer : EqualityComparer<KeyValuePair<string, int>>
+
{
+
  public override bool Equals(KeyValuePair<string, int> x, KeyValuePair<string, int> y)
+
  {
+
    // KeyValuePairのKeyを比較する
+
    return string.Equals(x.Key, y.Key);
+
  }
+

          
+
  public override int GetHashCode(KeyValuePair<string, int> obj)
+
  {
+
    // KeyValuePairのKeyからハッシュ値を取得する
+
    return obj.Key.GetHashCode();
+
  }
+
}
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    KeyValuePairEqualityComparer comparer = new KeyValuePairEqualityComparer();
+
    HashSet<KeyValuePair<string, int>> s1 = new HashSet<KeyValuePair<string, int>>(comparer);
+

          
+
    s1.Add(new KeyValuePair<string, int>("Dave", 1));
+
    s1.Add(new KeyValuePair<string, int>("Alice", 2));
+
    s1.Add(new KeyValuePair<string, int>("Alice", 99999));
+
    s1.Add(new KeyValuePair<string, int>("Bob", 3));
+
    s1.Add(new KeyValuePair<string, int>("Eve", 4));
+
    s1.Add(new KeyValuePair<string, int>("Charlie", 5));
+

          
+
    Print(s1);
+

          
+
    HashSet<KeyValuePair<string, int>> s2 = new HashSet<KeyValuePair<string, int>>(comparer);
+

          
+
    s2.Add(new KeyValuePair<string, int>("Alice", 3));
+
    s2.Add(new KeyValuePair<string, int>("Bob", 1));
+
    s2.Add(new KeyValuePair<string, int>("Charlie", 2));
+

          
+
    Print(s2);
+

          
+
    // 差集合を求める
+
    Console.WriteLine("[ExceptWith]");
+

          
+
    s1.ExceptWith(s2);
+

          
+
    Print(s1);
+
  }
+

          
+
  static void Print(HashSet<KeyValuePair<string, int>> s)
+
  {
+
    foreach (KeyValuePair<string, int> pair in s)
+
    {
+
      Console.Write("{0}:{1}, ", pair.Key, pair.Value);
+
    }
+

          
+
    Console.WriteLine();
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.Collections.Generic
+

          
+
' KeyValuePair(Of String, Integer)の等価性比較を行うIEqualityComparer(Of T)
+
Class KeyValueEqualityComparer
+
  Inherits EqualityComparer(Of KeyValuePair(Of String, Integer))
+

          
+
  Public Overrides Function Equals(ByVal x As KeyValuePair(Of String, Integer), ByVal y As KeyValuePair(Of String, Integer)) As Boolean
+
    ' KeyValuePairのKeyを比較する
+
    Return String.Equals(x.Key, y.Key)
+
  End Function
+

          
+
  Public Overrides Function GetHashCode(ByVal obj As KeyValuePair(Of String, Integer)) As Integer
+
    ' KeyValuePairのKeyからハッシュ値を取得する
+
    Return obj.Key.GetHashCode()
+
  End Function
+
End Class
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim comparer As New KeyValueEqualityComparer()
+
    Dim s1 As New HashSet(Of KeyValuePair(Of String, Integer))(comparer)
+

          
+
    s1.Add(New KeyValuePair(Of String, Integer)("Dave", 1))
+
    s1.Add(New KeyValuePair(Of String, Integer)("Alice", 2))
+
    s1.Add(New KeyValuePair(Of String, Integer)("Alice", 99999))
+
    s1.Add(New KeyValuePair(Of String, Integer)("Bob", 3))
+
    s1.Add(New KeyValuePair(Of String, Integer)("Eve", 4))
+
    s1.Add(New KeyValuePair(Of String, Integer)("Charlie", 5))
+

          
+
    Print(s1)
+

          
+
    Dim s2 As New HashSet(Of KeyValuePair(Of String, Integer))(comparer)
+

          
+
    s2.Add(New KeyValuePair(Of String, Integer)("Alice", 3))
+
    s2.Add(New KeyValuePair(Of String, Integer)("Bob", 1))
+
    s2.Add(New KeyValuePair(Of String, Integer)("Charlie", 2))
+

          
+
    Print(s2)
+

          
+
    ' 差集合を求める
+
    Console.WriteLine("[ExceptWith]")
+

          
+
    s1.ExceptWith(s2)
+

          
+
    Print(s1)
+
  End Sub
+

          
+
  Shared Sub Print(ByVal s As HashSet(Of KeyValuePair(Of String, Integer)))
+
    For Each pair As KeyValuePair(Of String, Integer) In s
+
      Console.Write("{0}:{1}, ", pair.Key, pair.Value)
+
    Next
+

          
+
    Console.WriteLine()
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
Dave:1, Alice:2, Bob:3, Eve:4, Charlie:5, 
+
Alice:3, Bob:1, Charlie:2, 
+
[ExceptWith]
+
Dave:1, Eve:4, 
+
}}
+

          
+
この例のKeyValuePairEqualityComparerではKeyの値のみを比較しているため、Valueにどのような値が格納されているかといったことは一切考慮されません。 Keyの値が同一であれば、Valueの値に関わらず同一の要素とみなされます。
 

        

        
~

          
**大小比較のカスタマイズ
+
*大小比較のカスタマイズ [#Comparison]
 
SortedSetのコンストラクタで適切なIComparer<T>インターフェイスを指定することで、要素の大小関係比較時の動作をカスタマイズ出来ます。 例えば、比較の際に大文字小文字を無視するようにするといったことが出来ます。 以下は、大文字小文字を無視し、アルファベット順とは逆順(Z-Aの順)になるようにソートするIComparer<string>を実装し、SortedListおよびSortedDictionaryでの並べ替え順をカスタマイズする例です。
SortedSetのコンストラクタで適切なIComparer<T>インターフェイスを指定することで、要素の大小関係比較時の動作をカスタマイズ出来ます。 例えば、比較の際に大文字小文字を無視するようにするといったことが出来ます。 以下は、大文字小文字を無視し、アルファベット順とは逆順(Z-Aの順)になるようにソートするIComparer<string>を実装し、SortedListおよびSortedDictionaryでの並べ替え順をカスタマイズする例です。
 

        

        
 
#tabpage(codelang=cs)
#tabpage(codelang=cs)
1204,13 808,7
 
True
True
 
}}
}}
 

        

        
~
IComparer<T>インターフェイスや実装例については[[programming/netfx/comparison/0_comparison]]を参照してください。
**SortedSetのみで提供される操作
+

          
+

          
+
*SortedSetのみで提供される操作
+
以下の操作はHashSetには用意されておらず、SortedSetのみで提供される操作です。
+

          
+
**最大値・最小値
 
SortedListクラスでは、&msdn(netfx,member,System.Collections.Generic.SortedSet`1.Max){Maxプロパティ};および&msdn(netfx,member,System.Collections.Generic.SortedSet`1.Min){Minプロパティ};で集合内での最大・最小の要素を取得することが出来ます。 &msdn(netfx,member,System.Collections.Generic.SortedSet`1.GetViewBetween){GetViewBetweenメソッド};を使うと、指定した範囲に該当する部分集合をSortedSet<T>で取得出来ます。
SortedListクラスでは、&msdn(netfx,member,System.Collections.Generic.SortedSet`1.Max){Maxプロパティ};および&msdn(netfx,member,System.Collections.Generic.SortedSet`1.Min){Minプロパティ};で集合内での最大・最小の要素を取得することが出来ます。 &msdn(netfx,member,System.Collections.Generic.SortedSet`1.GetViewBetween){GetViewBetweenメソッド};を使うと、指定した範囲に該当する部分集合をSortedSet<T>で取得出来ます。
 

        

        
 
#tabpage(codelang=cs)
#tabpage(codelang=cs)
1301,51 899,6
 
Max: Eve
Max: Eve
 
}}
}}
 

        

        
+
HashSetで最大・最小の要素を取得したい場合には、LINQの拡張メソッドである&msdn(netfx,member,System.Linq.Enumerable.Max){Maxメソッド};と&msdn(netfx,member,System.Linq.Enumerable.Min){Minメソッド};を使うことができます。
+

          
+
#tabpage(codelang=cs)
+
#code{{
+
using System;
+
using System.Collections.Generic;
+
using System.Linq;
+

          
+
class Sample
+
{
+
  static void Main()
+
  {
+
    HashSet<string> s = new HashSet<string>(new string[] {"Adams", "Cyndy", "Dave", "Bob", "Charlie", "Elliott", "Becky", "Alice", "Diana", "Eve"});
+

          
+
    // 最小値と最大値を表示
+
    Console.WriteLine("Mix: {0}", s.Min());
+
    Console.WriteLine("Max: {0}", s.Max());
+
  }
+
}
+
}}
+
#tabpage(codelang=vb)
+
#code{{
+
Imports System
+
Imports System.Collections.Generic
+
Imports System.Linq
+

          
+
Class Sample
+
  Shared Sub Main()
+
    Dim s As New HashSet(Of String)(New String() {"Adams", "Cyndy", "Dave", "Bob", "Charlie", "Elliott", "Becky", "Alice", "Diana", "Eve"})
+

          
+
    ' 最小値と最大値を表示
+
    Console.WriteLine("Mix: {0}", s.Min)
+
    Console.WriteLine("Max: {0}", s.Max)
+
  End Sub
+
End Class
+
}}
+
#tabpage-end
+

          
+
#prompt(実行結果){{
+
Mix: Adams
+
Max: Eve
+
}}
+

          
+

          
+
**逆順での列挙
 
&msdn(netfx,member,System.Collections.Generic.SortedSet`1.Reverse){Reverseメソッド};は、SortedSetを通常とは逆順に列挙する列挙子(IEnumerator<T>)を返します。 &msdn(netfx,member,System.Array.Reverse){Array.Reverseメソッド};や&msdn(netfx,member,System.Collections.Generic.List`1.Reverse){List.Reverseメソッド};とは異なり、コレクション内の要素の並びは変わりません。 Reverseメソッドを呼び出してもコレクション内の要素は逆順にはならず、あくまで逆順に列挙する列挙子を返すだけという点に注意してください。
&msdn(netfx,member,System.Collections.Generic.SortedSet`1.Reverse){Reverseメソッド};は、SortedSetを通常とは逆順に列挙する列挙子(IEnumerator<T>)を返します。 &msdn(netfx,member,System.Array.Reverse){Array.Reverseメソッド};や&msdn(netfx,member,System.Collections.Generic.List`1.Reverse){List.Reverseメソッド};とは異なり、コレクション内の要素の並びは変わりません。 Reverseメソッドを呼び出してもコレクション内の要素は逆順にはならず、あくまで逆順に列挙する列挙子を返すだけという点に注意してください。
 

        

        
 
#tabpage(codelang=cs)
#tabpage(codelang=cs)