เมธอด Equals(object) ของ HashSet<T> **ไม่ได้ Override** จาก Object ดังนั้นจึงเปรียบเทียบ **Reference Equality** (อ้างอิงออบเจ็กต์เดียวกัน) ไม่ใช่เปรียบเทียบเนื้อหาเซต
ตัวอย่างที่ 1: ออบเจ็กต์เดียวกัน (Reference) -> True
using System;
using System.Collections.Generic;
public class Demo
{
public static void Main(string[] args)
{
HashSet<string> set1 = new HashSet<string>();
set1.Add("A");
set1.Add("B");
set1.Add("C");
set1.Add("D");
set1.Add("E");
set1.Add("F");
set1.Add("G");
set1.Add("H");
Console.WriteLine("องค์ประกอบใน HashSet1...");
foreach (string res in set1)
{
Console.WriteLine(res);
}
HashSet<string> set2 = new HashSet<string>();
set2.Add("John");
set2.Add("Jacob");
set2.Add("Ryan");
set2.Add("Tom");
set2.Add("Andy");
set2.Add("Tim");
set2.Add("Steve");
set2.Add("Mark");
Console.WriteLine("องค์ประกอบใน HashSet2...");
foreach (string res in set2)
{
Console.WriteLine(res);
}
// set3 อ้างอิงไปที่ set2 เดียวกัน
HashSet<string> set3 = set2;
Console.WriteLine("HashSet3 เท่ากับ HashSet2? = " + set3.Equals(set2)); // True (Same Reference)
}
}
ผลลัพธ์
องค์ประกอบใน HashSet1... A B C D E F G H องค์ประกอบใน HashSet2... John Jacob Ryan Tom Andy Tim Steve Mark HashSet3 เท่ากับ HashSet2? = True
ตัวอย่างที่ 2: เนื้อหาเหมือนกันแต่ออบเจ็กต์ต่างกัน -> False
using System;
using System.Collections.Generic;
public class Demo
{
public static void Main(string[] args)
{
HashSet<string> set1 = new HashSet<string>();
set1.Add("A");
set1.Add("B");
set1.Add("C");
set1.Add("D");
set1.Add("E");
set1.Add("F");
set1.Add("G");
set1.Add("H");
Console.WriteLine("องค์ประกอบใน HashSet1...");
foreach (string res in set1)
{
Console.WriteLine(res);
}
HashSet<string> set2 = new HashSet<string>();
set2.Add("John");
set2.Add("Jacob");
set2.Add("Ryan");
set2.Add("Tom");
set2.Add("Andy");
set2.Add("Tim");
set2.Add("Steve");
set2.Add("Mark");
Console.WriteLine("องค์ประกอบใน HashSet2...");
foreach (string res in set2)
{
Console.WriteLine(res);
}
// เปรียบเทียบ set2 กับ set1 (คนละออบเจ็กต์)
Console.WriteLine("HashSet2 เท่ากับ HashSet1? = " + set2.Equals(set1)); // False
}
}
ผลลัพธ์
องค์ประกอบใน HashSet1... A B C D E F G H องค์ประกอบใน HashSet2... John Jacob Ryan Tom Andy Tim Steve Mark HashSet2 เท่ากับ HashSet1? = False
วิธีเปรียบเทียบเนื้อหา HashSet (Value Equality) - ใช้ SetEquals
HashSet<int> setA = new HashSet<int> { 1, 2, 3 };
HashSet<int> setB = new HashSet<int> { 3, 2, 1 }; // ลำดับต่างกัน
HashSet<int> setC = new HashSet<int> { 1, 2, 4 }; // เนื้อหาต่างกัน
// SetEquals: เปรียบเทียบสมาชิก (ไม่สนลำดับ) - แนะนำ!
Console.WriteLine(setA.SetEquals(setB)); // True
Console.WriteLine(setA.SetEquals(setC)); // False
// SequenceEqual (LINQ): ต้องการลำดับเหมือนกัน (HashSet ไม่มีลำดับรับประกัน -> ไม่แนะนำ)
// Console.WriteLine(setA.SequenceEqual(setB)); // อาจ False ได้
// Manual Comparison (Generic)
public static bool HashSetsEqual<T>(HashSet<T> a, HashSet<T> b)
{
if (ReferenceEquals(a, b)) return true;
if (a is null || b is null) return false;
return a.Count == b.Count && a.SetEquals(b);
}
เมธอดเซตสำคัญของ HashSet<T>
| เมธอด | คำอธิบาย | ใช้สำหรับ |
|---|---|---|
SetEquals(IEnumerable<T>) | สมาชิกเหมือนกันทุกตัว (ไม่สนลำดับ) | Value Equality ของ Set |
Overlaps(IEnumerable<T>) | มีสมาชิกร่วมกัน ≥ 1 | Intersection Check |
IsSubsetOf | A ⊆ B | Subset Check |
IsProperSubsetOf | A ⊂ B | Proper Subset |
IsSupersetOf | A ⊇ B | Superset Check |
IsProperSupersetOf | A ⊃ B | Proper Superset |
UnionWith | A ∪ B (In-Place) | Merge Sets |
IntersectWith | A ∩ B (In-Place) | Keep Common |
ExceptWith | A \ B (In-Place) | Remove Other |
SymmetricExceptWith | A Δ B (In-Place) | XOR Sets |
ข้อสังเกตสำคัญ
- HashSet.Equals = Reference Equality เท่านั้น (Default Object Behavior)
- **ใช้
SetEqualsสำหรับเปรียบเทียบเนื้อหาเซต** (คือคำตอบที่ถูกต้อง) - HashSet ไม่มีลำดับ ดังนั้น
SequenceEqual**ไม่เหมาะสม** (ผลลัพธ์ไม่แน่นอน) SetEqualsรับ IEnumerable<T> ใดๆ ก็ได้ (List, Array, HashSet อื่น)- Complexity: O(n) โดยประมาณ (n = ขนาดเซตเล็กกว่า)