【问题标题】:Collection of unique items with custom comparator使用自定义比较器收集独特项目
【发布时间】:2022-01-12 11:27:49
【问题描述】:

我需要collection,类似于std::set,所以每个元素只能插入一次,但是我需要提供我的自定义比较器来决定元素是否相等。 我怎么能在 C# 中做到这一点? 好像 C# 根本没有设置?

【问题讨论】:

    标签: c# .net .net-core collections compare


    【解决方案1】:

    .NET 带有一个称为HashSet<T> 的无序集合类型,其中的多个构造函数接受用户提供的IEqualityComparer<T> 实例:

    var set = new HashSet<string>(StringComparer.CurrentCultureIgnoreCase);
    
    set.Add("abc"); // the statement returns `true`
    set.Add("def"); // the statement returns `true`
    set.Add("abc"); // returns `false`, abc already exists in set
    
    set.Contains("abc"); // returns `true` as expected
    set.Contains("ABC"); // also `true`, thanks to our case-insensitive comparer
    

    【讨论】:

    • 但是使用自定义 IEqualityComparer Contains 函数似乎调用 GetHashCode 函数并比较元素哈希,而不是等于一,它接受两个项目作为参数..
    • @Random hashset 先使用GetHashCode,然后使用Equals
    • @GuruStron Contains 仅使用 GetHashCode,并比较 hashcodesm 而不是元素本身,这是我在调试器中看到的
    • @Random 无论您是否提供 IEqualityComparer 的自定义实现,情况都是如此 - GetHashCode() 是解析集合的底层类似哈希表的存储中的目标存储桶所必需的 - @987654332 @ 然后用于解决冲突。 See source
    • @Random 那么您需要检查您的自定义比较器和/或调试数据,因为Equals 显然是used。尽管出于显而易见的原因,它仅在哈希码匹配时才会使用。
    【解决方案2】:

    您要查找的对象是HashSet&lt;T&gt;,它只会添加一次。

    如果您想实现自己的相等比较,可以让类实现 IEqualityComparer&lt;T&gt; 并在那里提供相等的逻辑。

    【讨论】:

      【解决方案3】:

      您想要一个带有自定义 IEqualityComparer&lt;T&gt; 实例的 HashSet

      【讨论】:

        【解决方案4】:

        您可以使用SortedSet&lt;T&gt;,其中constructor 接受custom IComparer,并且不允许重复项:

        SortedSet 对象在插入和删除元素时保持排序顺序而不影响性能。 不允许重复元素。不支持更改现有项目的排序值,这可能会导致意外行为。

        或者SortedDictionary&lt;TKey,TValue&gt;custom comparer 作为键。

        【讨论】:

          猜你喜欢
          • 2014-03-08
          • 1970-01-01
          • 1970-01-01
          • 2020-04-20
          • 2017-11-02
          • 2019-07-08
          • 2018-10-31
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多