我想使用HashSet.Contains方法,因为它超级快。
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM, dd, yyyy"
let raceDate = raceDateTextField.text
let date = dateFormatter.date(from: raceDate!)
let minimumDate = NSDate()
if minimumDate.compare(date!) == ComparisonResult.orderedDescending {
}
我在客户对象上搜索多个属性。
我必须实现IEqualityComparer接口,如:
var hashset = new HashSet<Customer>(customers, new CustomerComparer());
var found = hashset.Contains(new Customer{ Id = "1234", Name = "mit" }); // "mit" instead of an equals "smith" in the comparer.
为什么在我不在.Contains之类的CustomerComparer Equals方法中使用Equals方法时,Equals方法永远不会出现?
答案 0 :(得分:4)
您实现相等比较器的方式无法正常工作。原因是哈希集和相等比较器如何在内部工作。当Dictionary
或HashSet
对项目进行比较时,它会首先在两个项目上调用GetHashCode
。只有当这些哈希码匹配时,它才会确认与后续调用Equals
的完全匹配,以避免在哈希码冲突的情况下出现错误匹配。如果您使用示例(x.Name = "smith"
和y.Name = "mit"
),GetHashCode
方法将为每个项返回不同的哈希码,并且永远不会调用Equals
。
这种情况下的解决方案是仅使用Id
创建哈希码。这会降低性能,因为你需要更频繁地调用Equals
来解决冲突,但这是你必须付出的代价:
public int GetHashCode(Customer obj)
{
return obj.Id.GetHashCode() ;
}
您还应该考虑的是,您无法保证现有项目是x
还是y
。因此,您必须在两个方向都使用Contains
:
public bool Equals(Customer x, Customer y)
{
return x.Id == y.Id && (x.Name.Contains(y.Name) || y.Name.Contains(x.Name));
}
答案 1 :(得分:0)
为什么在我不在.Contains之类的CustomerComparer Equals方法中使用Equals方法时,Equals方法永远不会出现?
只有当您的&#34;客户&#34;中至少有一个项目出现时,才会触发Equals方法。与您传递给HashSet的Contains方法的Customer对象具有相同哈希码的集合。如果运行以下示例程序,您将看到Equals方法确实被命中:
public static class Program
{
public class Customer
{
public string Id { get; set; }
public string Name { get; set; }
}
public class CustomerComparer : IEqualityComparer<Customer>
{
public bool Equals(Customer x, Customer y)
{
Console.WriteLine("hit!");
return x.Id == y.Id && x.Name.Contains(y.Name);
}
public int GetHashCode(Customer obj)
{
return obj.Id.GetHashCode() ^ obj.Name.GetHashCode();
}
}
public static void Main()
{
List<Customer> customers = new List<Customer>()
{
new Customer() { Id = "1234", Name = "smith" },
new Customer() { Id = "1234", Name = "mit" }
};
var hashset = new HashSet<Customer>(customers, new CustomerComparer());
var found = hashset.Contains(new Customer { Id = "1234", Name = "mit" }); // "mit" instead of an equals "smith" in the comparer.
Console.WriteLine(found); // = true
}
}
但如果您从&#34;客户&#34;中删除第二项列出自&#34;史密斯&#34;的哈希码以来不会被击中的等于方法。列表中的客户具有与&#34; smith&#34;不同的哈希码。传递给Contains方法的客户:
List<Customer> customers = new List<Customer>()
{
new Customer() { Id = "1234", Name = "smith" }
};