循环遍历数据对象的字符串构造唯一的不同集合

时间:2015-11-27 10:58:37

标签: c# string performance recursion collections

我不知道如何,但是几周以来我一直在使用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>就可以了解商业&#34;

我还没有考虑过它会允许重复的选项但是在这个项目中我把它放到了测试中它确实让我惊讶地添加了一个现有的项目 所以我的工作是:

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()
        {

        }
    }

2 个答案:

答案 0 :(得分:1)

Ypu希望您HashSet能够照顾生意&#34;。 HashSet正是这样做的。但是你首先必须让它知道你认为是什么&#34;重复&#34; (或者更确切地说,当您的对象应该被视为相等时)。为此,您应该在GetHashCode()类上实现(覆盖)myHddFolderPaths方法。

How does HashSet compare elements for equality?

Implementing GetHashCode correctly

Default implementation for Object.GetHashCode()

答案 1 :(得分:1)

使用无参数构造函数创建的HashSet使用默认的相等比较器。 default comparer将使用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提供的默认实现,检查引用相等。

您现在有两种选择。一种是覆盖Equals中的GetHashCodeFolderPath

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

并将其传递给HashSet构造函数。

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