为什么集合有单独的等于方法
本文关键字:方法 于方法 集合 单独 为什么 | 更新日期: 2023-09-27 18:19:08
在C Sharp .NET中,有一个Equals
方法和一个SetEquals
方法。区别在哪里?
来自Java,我的第一个想法是SetEquals
不是必需的,只需对所有对象使用Equals
方法即可。
SetEquals
不遵守与Equals
相同的契约。特别是它不是对称的,因为参数只是IEnumerable<T>
而不是ISet<T>
。这允许您在只有一个集合的情况下检查集合相等性。考虑:
List<int> intList = new List<int> { 1, 2, 3 };
HashSet<int> intSet = new HashSet<int>(intList);
现在我们可以使用:
Console.WriteLine(intSet.SetEquals(intList));
。但是,如果不对List<int>
和所有其他IEnumerable<T>
实现强制执行相同的行为,我们就无法以相同的方式实现Equals
。
即使我们将其限制在其他集合中,也存在一个有趣的问题,即平等的真正含义。例如,考虑两个包含相同字符串但具有不同相等比较器的HashSet<string>
集。(也许一个区分大小写,一个不区分大小写。这些是平等的,还是不平等的? SetEquals
设法避免了这种哲学问题,避免了过于笼统。
HashSet<int>
和SortedSet<int>
呢?他们能平等吗?它们可以具有相同的值 - 但一个值的顺序是未定义的。
总的来说,在我看来,Object.Equals
和Object.GetHashCode
的想法过于宽泛。通常,您需要一种特定类型的相等性 - 通常首先比较对象的相等性是没有意义的。这很容易形成一个完全不同的咆哮的主题,但与此同时,我至少很高兴 .NET 没有尝试将这个过于宽泛的想法应用于集合。IMO,使用具有明确含义的SetEquals
的能力更有用。
HashSet<T>.SetEquals
确定哈希集是否包含与给定IEnumerable<T>
相同的元素。但是,如果类型不同,为什么还要返回 true?
HashSet<int> h = new HashSet<int>();
h.Add(0);
h.Add(1);
int[] ints = new[] { 0, 1, 1, 0 };
h.SetEquals(ints); // true, ignores duplicates because it's a set
h.Equals(ints); // false, correct because not even the same types
MSDN:
方法忽略重复的条目和 元素在另一个参数中.....
由于HasetSet<T>
不会覆盖Equals
因此它使用从对象继承的那个,该对象只是比较引用。因此,如果两个对象不是相同的引用,则返回false
.
-
Equals
将测试两个HashSet
是否是同一个对象。 -
SetEquals
接受一个IEnumerable<T>
,它的作用是:">SetEquals 方法忽略重复条目和元素在其他参数中的顺序。
因此,SetEquals
用于测试以查看您是否将IEnumerable加载到HashSet中,它是否会生成与您的源相同的HashSet。
Equals
检查两者之间的引用相等性,SetEquals
将检查集合上的元素。
SetEquals:
检查哈希集是否包含与给定的 IEnumerable
<T>
相同的元素。方法将第二个集合视为没有重复元素。如果存在重复元素,则两个集合仍可能被视为相等。
等于:
等于实际上是一个参考测试
List<string> stringList = new List<string> { "a", "b", "c" };
SortedSet<string> stringSet = new SortedSet<string> { "a", "b", "c" };
bool a = stringSet.SetEquals(stringList );
// See if the two collections contain the same elements.
public static void Main(string[] args)
{
Console.WriteLine("Hello World!");
System.Collections.Generic.HashSet<int> setA= new System.Collections.Generic.HashSet<int>();
setA.Add(1);
System.Collections.Generic.HashSet<int> setB= new System.Collections.Generic.HashSet<int>();
setB.Add(1);
Console.WriteLine("Equals method returns {0}", setA.Equals(setB));
Console.WriteLine("SetEquals method returns {0}", setA.SetEquals(setB));
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true);
}
产生输出:等于方法返回假SetEquals 方法返回 True
因此,equals方法似乎是对参照相等的测试。
ISet<T>.SetEquals
继承确定当前集和指定的集合是否包含相同的元素。
自object
的Equals
实现
等效于对 ReferenceEquals 方法的调用。
继承的 ReferenceEquals 实现,
确定指定的 Object 实例是否为同一实例。
请注意,传递给 SetEquals
的 IEnumerable<T>
序列可以按任何顺序具有集合中每个成员的一个或多个实例,并且SetEquals
仍将返回 true。
如果要确认两个序列以相同的顺序包含完全相同的成员,则可以使用 SequenceEqual
扩展。