A Python developer doing some C# (.NET 4.6, Visual Studio 2015 Professional) work here. I am trying to check whether two HashSet
s are equal.
I have two HashSet<List<float>>
which I am trying to compare using
thisList.SetEquals(otherList);
However, this returns false
on my data. Using the sample from the MSDN HashSet
's examples does work as expected. However, in the samples they use HashSet<int>
whereas I use HashSet<List<float>>
.
As I could not found a way to print the HashSet
contents into Immediate Window in Visual Studio ( ToString
returns "System.Collections.Generic.HashSet1[System.Collections.Generic.List1[System.Single]]"
), I use Json.NET JsonConvert.SerializeObject(thisList);
to dump the data into a .json
file on disk.
Two files (each for each HashSet
contents is:
[[10.0,15.0],[20.0,25.0]]
and [[10.0,15.0],[20.0,25.0]]
Inspecting the HashSet
s in Visual Studio while debugging looks like this:
- thisList Count = 2 System.Collections.Generic.HashSet<System.Collections.Generic.List<float>>
- [0] Count = 2 System.Collections.Generic.List<float>
[0] 10 float
[1] 15 float
+ Raw View
- [1] Count = 2 System.Collections.Generic.List<float>
[0] 20 float
[1] 25 float
+ Raw View
+ Raw View
- otherList Count = 2 System.Collections.Generic.HashSet<System.Collections.Generic.List<float>>
- [0] Count = 2 System.Collections.Generic.List<float>
[0] 20 float
[1] 25 float
+ Raw View
- [1] Count = 2 System.Collections.Generic.List<float>
[0] 10 float
[1] 15 float
+ Raw View
+ Raw View
Each HashSet
contains two lists (order is not of relevance, since it is a set) and each list has identical values (with the same order). They should be considered equal.
What should I do to make these HashSet
s to be considered equal with thisList.SetEquals(otherList);
?
EDIT:
Printing coord.ToString("G17")
on each float:
10
15
20
25
20
25
10
15
Because you are using List in your HashSet, it is comparing the two lists as references instead of considering the values in the Lists.
Instead of using a List to represent an X and Y, use a Vector2 or Point class. This is more or less what the struct should look like:
public struct Point
{
public double X {get; }
public double Y { get; }
public Point(double x, double y)
{
X = x;
Y = y;
}
public bool Equals(Point other)
{
return X.Equals(other.X) && Y.Equals(other.Y);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
return obj is Point && Equals((Point) obj);
}
public override int GetHashCode()
{
unchecked
{
return (X.GetHashCode() * 397) ^ Y.GetHashCode();
}
}
}
You are trying to check equal operation of HashSet<List<float>>
with another object of HashSet<List<float>>
. The question here is that why it is returning false ?
Now, before we talk about HashSet<List<float>>
, let's talk about if I check equal (using below code) for List<float>
with another object of List<float>
, then what would be the output?
List<float> list = new List<float>() { 10.0f, 15.0f};
List<float> anotherList = new List<float>() { 10.0f, 15.0f};
Console.WriteLine(list.Equals(anotherList));
The output of this will be
false
Since here Equals
compare the references of the objects (which aren't equal).
Now to solution to your problem
You should provide a EqualityComparer
while initializing the HashSet which should check the type T as needed.
HashSet<List<float>> HashSet1 = new HashSet<List<float>>(new FloatListComparer());
anotherHashSet1.Add(list);
HashSet<List<float>> anotherHashSet2 = new HashSet<List<float>>();
anotherHashSet2.Add(anotherList);
Console.WriteLine(anotherHashSet1.SetEquals(anotherHashSet2));
The output of above code is
true
The EqualityComparer
I've written here is looks like as follows.
public class FloatListComparer : EqualityComparer<List<float>>
{
public override bool Equals(List<float> list1, List<float> list2)
{
return list1.SequenceEqual(list2);
}
public override int GetHashCode(List<float> s)
{
return base.GetHashCode();
}
}
Now question here is that why SetEquals
is not working
If you check the implementation of SetEquals
at here , then you will find that it calls the default comparer of T which works based on checking the reference of objects. By providing the Comparer, SetEquals
uses the specified one.
Check the live fiddler here .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.