Подтвердить что ты не робот

Почему существует отдельный метод equals для множеств?

В C Sharp.NET существует метод Equals и метод SetEquals. Где разница?

Начиная с Java, моя первая мысль заключалась в том, что SetEquals не требуется, просто используйте метод Equals для всех объектов.

4b9b3361

Ответ 1

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));

... но мы не смогли реализовать Equals таким же образом, не применяя такое же поведение к List<int> и к любой другой реализации IEnumerable<T>.

Даже если мы ограничили его другими наборами, есть интересный вопрос о том, что означает на самом деле равенство. Например, рассмотрим два набора HashSet<string>, которые содержат одни и те же строки, но имеют разные сопоставители равенства. (Возможно, один из них чувствителен к регистру, а другой нет.) Являются ли они равными или нет? SetEquals удается избежать таких философских вопросов, избегая попыток быть слишком общим.

Как насчет HashSet<int> и a SortedSet<int>? Могут ли они когда-либо быть равными? Они могут иметь одинаковые значения, но порядок одного составляет undefined.

В целом идеи Object.Equals и Object.GetHashCode слишком широки, на мой взгляд. Часто вам нужен определенный тип равенства - и часто нет смысла сравнивать объекты на равенство в первую очередь. Это может легко стать предметом совершенно другого разговора, но тем не менее я, по крайней мере, рад, что .NET не пыталась применить эту слишком широкую идею к коллекциям. Способность использовать SetEquals с четко определенным значением более полезна, ИМО.

Ответ 2

HashSet<T>.SetEquals определяет, содержит ли HashSet те же элементы, что и данный 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 a set
h.Equals(ints); // false, correct because not even the same types

MSDN:

Метод SetEquals игнорирует повторяющиеся записи и порядок элементов в другом параметре.....

Так как HasetSet<T> не переопределяет Equals, он использует объект, унаследованный от объекта, который просто сравнивает ссылки. Поэтому, если два объекта не являются одной и той же ссылкой, он возвращает false.

Ответ 3

  • Equals будет проверять, являются ли два HashSet одним и тем же объектом.
  • SetEquals принимает IEnumerable<T>, что он делает: "Метод SetEquals игнорирует повторяющиеся записи и порядок элементов в другой параметр".

Итак, SetEquals предназначен для тестирования, чтобы увидеть, загружен ли IEnumerable в HashSet, генерирует ли он тот же HashSet, что и ваш источник.

Ответ 4

Equals проверяет ссылочное равенство между двумя и SetEquals будет проверять элементы в коллекции.

Ответ 5

SetEquals:

Проверяет, содержит ли HashSet те же элементы, что и указанный IEnumerable <T>.

Метод SetEquals рассматривает второй сборник, как будто он не имеет повторяющихся элементов. Если присутствуют повторяющиеся элементы, две коллекции могут по-прежнему считаться равными.

Равно:

Равные значения фактически являются ссылочным тестом

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.

Ответ 6

ISet<T>.SetEquals реализация

Определяет, содержат ли текущий набор и указанный набор те же элементы.

Equals реализация, унаследованная от object

эквивалентен вызову метода ReferenceEquals.

Унаследованная ReferenceEquals реализация,

Определяет, являются ли указанные экземпляры объекта одним и тем же экземпляром.


В paticular обратите внимание, что последовательность IEnumerable<T>, переданная в SetEquals, может иметь один или несколько экземпляров каждого члена набора в любом порядке, а SetEquals все равно вернет true.


Если вы хотите подтвердить, что две последовательности содержат точно такие же элементы в том же порядке, вы можете использовать расширение SequenceEqual.

Ответ 7

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);
        }

Производит вывод: Метод Equals возвращает False Метод SetEquals возвращает True

Таким образом, метод equals является испытанием на ссылочное равенство.