简体   繁体   English

比较两个包含很多对象的列表(第二部分)

[英]Compare two lists that contain a lot of objects (2th part)

Referring to the question that I previously asked: Compare two lists that contain a lot of objects 提到我之前提出的问题: 比较两个包含很多对象的列表

It is impressive to see how fast that comparison is maide by implementing the IEqualityComparer interface: example here 令人印象深刻的是,通过实现IEqualityComparer接口,可以快速地进行比较: 此处的示例

As I mentioned in my other question this comparison helps me to backup a sourse folder on a destination folder. 正如我在其他问题中提到的那样,此比较有助于我将源文件夹备份到目标文件夹中。 Know I want to sync to folders therefore I need to compare the dates of the files. 知道我想同步到文件夹,因此我需要比较文件的日期。 Whenever I do something like: 每当我做类似的事情:

public class MyFileComparer2 : IEqualityComparer<MyFile>
{

    public bool Equals(MyFile s, MyFile d)
    {
        return
            s.compareName.Equals(d.compareName) &&
            s.size == d.size &&
            s.deepness == d.deepness &&
            s.dateModified.Date <= d.dateModified.Date;  // This line does not work. 
            // I also tried comparing the strings by converting it to a string and it does
            // not work. It does not give me an error but it does not seem to include the files
            // where s.dateModified.Date < d.dateModified.Date

    }

    public int GetHashCode(MyFile a)
    {
        int rt = (a.compareName.GetHashCode() * 251 + a.size.GetHashCode() * 251 + a.deepness.GetHashCode() + a.dateModified.Date.GetHashCode());

        return rt;

    }
}

It will be nice if I could do something similar using greater or equal than signs. 如果我可以使用大于或等于符号的方式做类似的事情,那就太好了。 I also tried using the tick property and it does not work. 我也尝试使用tick属性,但它不起作用。 Maybe I am doing something wrong. 也许我做错了什么。 I believe it is not possible to compare things with the less than equal sign implementing this interface. 我相信无法将实现此接口的小于等号的事物进行比较。 Moreover, I don't understand how this Class works; 而且,我不了解该课程的工作方式; I just know it is impressive how fast it iterates through the whole list. 我只知道在整个列表中进行迭代的速度如此之快令人印象深刻。

Your whole approach is fundementally flawed because your IEqualityComparer.Equals method is not symmetric. 您的整个方法从根本上来说都是有缺陷的,因为您的IEqualityComparer.Equals方法不是对称的。 This means Equals(file1, file2) does not equal Equals(file2, file1) because of the way you are using the less than operator. 这意味着由于您使用小于运算符的方式Equals(file1, file2)不等于Equals(file2, file1)

The documentation: 文件:

clearly states: 明确指出:

Notes to Implementers 实施者须知

The Equals method is reflexive, symmetric, and transitive. 等于方法是自反,对称和可传递的。 That is, it returns true if used to compare an object with itself; 也就是说,如果用于将对象与其自身进行比较,则返回true;否则,返回true。 true for two objects x and y if it is true for y and x; 如果两个对象x和y为y,则为true;否则为true。 and true for two objects x and z if it is true for x and y and also true for y and z. 如果两个对象x和z分别为true和y和z,则为true。

Implementations are required to ensure that if the Equals method returns true for two objects x and y, then the value returned by the GetHashCode method for x must equal the value returned for y. 需要实现以确保如果Equals方法为两个对象x和y返回true,则GetHashCode方法为x返回的值必须等于为y返回的值。

Instead you need to use the IComparable interface or IEqualityComparer in combination with date comparisions. 相反,您需要结合使用IComparable接口或IEqualityComparer与日期比较。 If you do not, things might seem to work for a while but you will regret it later. 如果您不这样做,那么事情似乎会持续一段时间,但您稍后会后悔。

Since the DateTime objects are different in the case when one DateTime is less than the other, you get different hashcodes for the objects s and d and the Equals method is not called. 由于当一个DateTime小于另一个DateTime时,DateTime对象是不同的,因此对于对象sd ,您将获得不同的哈希码,并且不会调用Equals方法。 In order for your comparison of the dates to work, you should remove the date part from the GetHashCode method: 为了比较工作日期,应从GetHashCode方法中删除日期部分:

public int GetHashCode(MyFile a)
{
    int rt = ((a.compareName.GetHashCode() * 251 + a.size.GetHashCode())
                          * 251 + a.deepness.GetHashCode()) *251;

    return rt;

}

Your GetHashCode has a problem: 您的GetHashCode有问题:

public int GetHashCode(MyFile a)
{
    int rt = (((a.compareName.GetHashCode() * 251) 
           + a.size.GetHashCode() * 251)
           + a.deepness.GetHashCode() *251) 
           + a.dateModified.Date.GetHashCode();

    return rt;

}

I changed the date part because I also needed the time therefore I use the ticks property instead. 我更改了日期部分,因为我还需要时间,因此我改用了ticks属性。 I got rid of the dateModified hashed code and it works great. 我摆脱了dateModified哈希码,效果很好。 here is how I modified my program. 这是我修改程序的方式。 I was having trouble comparing the dates therefore I used the Ticks property. 我在比较日期时遇到了麻烦,因此我使用了Ticks属性。

public class MyFileComparer2 : IEqualityComparer<MyFile>
{

    public bool Equals(MyFile s, MyFile d)
    {
        return
            s.compareName.Equals(d.compareName) &&
            s.size == d.size &&
            s.deepness == d.deepness &&
            //s.dateModified.Date <= d.dateModified.Date &&
            s.dateModified.Ticks >= d.dateModified.Ticks
            ;  

    }

    public int GetHashCode(MyFile a)
    {
        int rt = (((a.compareName.GetHashCode() * 251)
                + a.size.GetHashCode() * 251)
                + a.deepness.GetHashCode() * 251)
                //+ a.dateModified.Ticks.GetHashCode();                       
                ;

        return rt;

    }
}

I still don't know how this hash code function works. 我仍然不知道此哈希码功能如何工作。 The nice thing is that it works great. 令人高兴的是,它运作良好。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM