在字符串的数据对象上循环构造一个唯一的不同集合

本文关键字:一个 唯一 集合 对象 数据 字符串 循环 | 更新日期: 2023-09-27 18:24:39

我不知道是怎么回事,但几个星期以来,我一直在使用主要由字符串成员组成的HashSet<myObject>集合,尽管它在内部使用了一种内置的方法作为字典,以避免非KVP格式的数据(单列)中的重复项

我的设想是:

HashSet<myHddFolderPaths> UniqColleciton = new HashSet<myHddFolderPtahs>
int countRounds=0;
void addToCollection()
{
    for(int i=0, i < UniqColleciton.Count; i++)
    {
        add some items to UniqColleciton via Directory.GetDirectories();
    }
    if(countRounds++ < Limit)  
       addToCollection()
}

这是我正在构建的dir walker的模式,这只是一个无法避免重复出现相同数据的场景的例子,所以我不记得我在哪里读过它,也不记得我认为简单地使用HashSet<T>就可以"处理业务"

我还没有想过允许重复的选项,但在这个项目中,我对它进行了测试,它确实允许添加现有的项,这让我感到惊讶所以我的工作是:

Dictionary<string, int> fiterAccesDeniedPaths = new Dictionary<string, int>();
Dictionary<string, int> fiterAccesiblePaths = new Dictionary<string, int>();
if (this.fiterAccesDeniedPaths.ContainsKey(e.Message)) continue;
if (this.fiterAccessiblePaths.ContainsKey(object.stringPathMember)) continue;
add to filters ; UniqColleciton.Add(myHddFolderPaths);

是否有更好/更有效的方法来完成此任务

public class FolderPath
{
    public string DriveL { get; set; }
    public string FolderLevel { get; set; }
    public string Path { get; set; }
    public int Fsize { get; set; }
}

    public class GenericUniqCollectionM<T> : HashSet<T>
    {
        public GenericUniqCollectionM():base()
        {
        }
    }

在字符串的数据对象上循环构造一个唯一的不同集合

使用无参数构造函数创建的HashSet使用默认的相等比较器。默认比较器将使用FolderPath.Equals()来检查相等性。
internal class ObjectEqualityComparer<T> : EqualityComparer<T>
{
    public override bool Equals(T x, T y)
    {
        if (x != null)
        {
            if (y != null) return x.Equals(y);
            return false;
        }
        if (y != null) return false;
        return true;
    }
    public override int GetHashCode(T obj)
    {
        if (obj == null) return 0;
        return obj.GetHashCode();
    }
    ...
}

您没有覆盖EqualsGetHashCode,所以它将使用object提供的默认实现,检查引用相等性。

你现在有两个选择。一种是覆盖FolderPath中的EqualsGetHashCode

public class FolderPath
{
    ...
    public override bool Equals(object obj)
    {
        if (obj == null) return false;
        FolderPath other = obj as FolderPath;
        if (other == null) return false;
        //simple implementation, only compares Path
        return Path == other.Path;
    }
    public override int GetHashCode()
    {
        if (Path == null) return 0;
        return Path.GetHashCode();
    }
}

另一个是实现自定义的IEqualityComparer<FolderPath>

public class FolderPathComparer : IEqualityComparer<FolderPath>
{
    public bool Equals(FolderPath x, FolderPath y)
    {
        if (x != null)
        {
            if (y != null) return x.Path == y.Path;
            return false;
        }
        if (y != null) return false;
        return true;
    }
    public int GetHashCode(FolderPath obj)
    {
        if (obj == null || obj.Path == null) return 0;
        return obj.Path.GetHashCode();
    }
}

并将其传递给CCD_ 12构造函数。

var set = new HashSet<FolderPath>(new FolderPathComparer());

Ypu希望您的HashSet"处理好业务"。HashSet正是这样做的。但你首先必须让它知道你认为什么是"重复"(或者更确切地说,什么时候你的对象应该被认为是相等的)。为此,您应该在myHddFolderPaths类上实现(重写)GetHashCode()方法。

HashSet如何比较元素的相等性?

正确实现GetHashCode

Object.GetHashCode()的默认实现