c# - 为什么我不能在没有枚举的情况下从 HashSet 中检索项目?

标签 c# java hashset

我正在寻找 HashSet 设计者的头脑。据我所知,我的问题同时适用于 Java 和 C# HashSet,这让我认为这一定有一些充分的理由,尽管我自己也想不出来。

我在HashSet中插入了一个item,为什么不通过枚举就无法检索到那个item,几乎不是一个高效的操作?特别是因为 HashSet 是以一种支持高效检索的方式显式构建的。

让 Remove(x) 和 Contains(x) 返回被删除或包含的实际项目通常对我很有用。这不一定是我传递给 Remove(x) 或 Contains(x) 函数的项目。当然,我想我可以通过 HashMap 实现相同的效果,但是当完全可以使用集合来实现这一点时,为什么还要浪费所有的空间和精力呢?

我理解可能存在一些设计问题,即添加此功能将允许使用与其在框架中的角色或 future 角色不一致的 HashSet,但如果是这样,这些设计问题是什么?

编辑

要回答更多问题,这里有更多详细信息:

我在 C# 中使用具有覆盖哈希码、等号等的不可变引用类型来模拟值类型。假设该类型具有成员 A、B 和 C。Hashcode、equals 等仅取决于 A 和 B。给定一些 A 和 B,我希望能够从哈希集中检索该等价项并得到它的 C。我赢了似乎无法为此使用 HashSet,但我至少想知道是否有任何充分的理由。伪代码如下:

public sealed class X{
 object A;
 object B;
 object extra;

 public int HashCode(){
  return A.hashCode() + B.hashCode();
 }

 public bool Equals(X obj){
  return obj.A == A && obj.B == B;
 }
}

hashset.insert(new X(1,2, extra1));
hashset.contains(new X(1,2)); //returns true, but I can't retrieve extra

最佳答案

在 .Net 中,您可能正在寻找的是 KeyedCollection http://msdn.microsoft.com/en-us/library/ms132438.aspx

您可以通过一些“通用”的聪明才智来解决每次重新实现这个抽象类的麻烦。 (参见 IKeyedObject`1。)

注意:任何实现 IKeyedObject`1 的数据传输对象都应该有一个重写的 GetHashCode 方法,只需返回 this.Key.GetHashCode();等号也一样...

我的基类库中通常会出现这样的内容:

public class KeyedCollection<TItem> : System.Collections.ObjectModel.KeyedCollection<TItem, TItem>
    where TItem : class
{
    public KeyedCollection() : base()
    {
    }

    public KeyedCollection(IEqualityComparer<TItem> comparer) : base(comparer)
    {
    }

    protected override TItem GetKeyForItem(TItem item)
    {
        return item;
    }
}

public class KeyedObjectCollection<TKey, TItem> : System.Collections.ObjectModel.KeyedCollection<TKey, TItem>
    where TItem : class, IKeyedObject<TKey>
    where TKey : struct
{
    public KeyedCollection() : base()
    {
    }

    protected override TItem GetKeyForItem(TItem item)
    {
        return item.Key;
    }
}

///<summary>
/// I almost always implement this explicitly so the only
/// classes that have access without some rigmarole
/// are generic collections built to be aware that an object
/// is keyed.
///</summary>
public interface IKeyedObject<TKey>
{
    TKey Key { get; }
}

关于c# - 为什么我不能在没有枚举的情况下从 HashSet 中检索项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1494812/

相关文章:

c# - 使用 LINQ 查询获取索引值的集合

java - 添加到 HashSet 时出现空指针异常

java - 计算大长数组中的不同值(性能问题)

c# - 在 MVC 中初始化基本 Controller 时

c# - 如何获取枚举描述的字符串列表?

c# - 有什么理由我们不能在元组周围添加一些语法糖吗?

java - 使用 Scanner.hasNextInt 无限循环

java - 为什么 success 函数在 spring mvc 中不起作用

java - 如何获取JAVA文件夹中所有视频的时长?

java - 奇怪的 Set.contains() 行为