等価性比較のカスタマイズ例として、HashSetでKeyValuePairを扱う例をみてみます。 次の例では、KeyValuePairからKeyの値を取得して比較を行うクラスKeyValuePairEqualityComparerを作成し、それをHashSetのコンストラクタに渡しています。 これによりKeyValuePair同士の比較ができるようになり、HashSetでKeyValuePairを扱うことができるようになります。
HashSetでKeyValuePairを扱う
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))
Console.WriteLine(String.Join(", ", 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))
Console.WriteLine(String.Join(", ", s2))
' 差集合を求める
Console.WriteLine("[ExceptWith]")
s1.ExceptWith(s2)
Console.WriteLine(String.Join(", ", s1))
End Sub
End Class
実行結果
[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の値に関わらず同一の要素とみなされます。