c# - 如何检查HashSet> 包含列表的重复值在 C# 中?
问题描述
我在 C# 中有一个 HashSet,如下所示:
HashSet<List<int>> _hash = new HashSet<List<int>>();
现在,我在其中插入了一个值,如下所示:
_hash.add(new List<int> {1,7});
当我在上面的代码之后编写以下代码时:
_hash.contains(new List<int>{1,7});
我期待它返回 true,因为刚刚添加了相同的值,但它确实返回了 false。这让我感到困惑。此外,我如何确保当我确实有一个 List 哈希集时,在我向其中添加任何新值之前其中没有重复项。
我认为使用 HashSet 背后的全部原因是为了避免任何重复,但似乎这个允许重复。
现在,从长远来看,我想要的只是当我有一个 List> 时,我如何确保进入 List> 的每个元素(List)都是唯一的?
解决方案
您可以创建自己的可比较的只读集合。
public class ComparableReadOnlyCollection<T> : ReadOnlyCollection<T>
{
public ComparableReadOnlyCollection(IList<T> list)
: base(list.ToArray())
{
}
public override bool Equals(object other)
{
return
other is IEnumerable<T> otherEnumerable &&
otherEnumerable.SequenceEqual(this);
}
public override int GetHashCode()
{
int hash = 43;
unchecked {
foreach (T item in this) {
hash = 19 * hash + item.GetHashCode();
}
}
return hash;
}
}
请注意,这ReadOnlyCollection<T>
只是原始列表的包装。如果您修改此列表,则会ReadOnlyCollection<T>
反映这些更改。我的实现将原始列表复制到一个数组以使其真正不可变。
但请注意,如果元素T
是引用类型,您仍然可以修改原始对象的成员!所以要小心。
此测试按预期工作:
var hashSet = new HashSet<ComparableReadOnlyCollection<int>>();
hashSet.Add(new ComparableReadOnlyCollection<int>(new [] { 1, 7 }));
Console.WriteLine(hashSet.Contains(new ComparableReadOnlyCollection<int>(new [] { 1, 7 })));
Console.WriteLine(hashSet.Contains(new ComparableReadOnlyCollection<int>(new [] { 7, 1 })));
Console.WriteLine(hashSet.Contains(new ComparableReadOnlyCollection<int>(new [] { 1, 7, 0 })));
hashSet.Add(new ComparableReadOnlyCollection<int>(new [] { 1, 7 }));
hashSet.Add(new ComparableReadOnlyCollection<int>(new [] { 1, 7, 0 }));
hashSet.Add(new ComparableReadOnlyCollection<int>(new [] { 7, 1 }));
Console.WriteLine(hashSet.Count);
Console.ReadKey();
它打印
True
False
False
3
请注意,它不会打印 4,因为集合中不能有重复项。
第二种解决方案:
阅读您的编辑后,我不确定您真正想要什么。您的意思是创建 aHashSet<int>
而不是 aHashSet<List<int>>
并比较列表的元素而不是列表本身吗?
HashSet<int> _hash = new HashSet<int>(new List<int> { 1, 1, 2, 3, 5, 8, 13 });
现在哈希集包含数字 { 1, 2, 3, 5, 8, 13 }。集合元素总是唯一的。
然后你可以测试
var hash2 = new HashSet<int> { 3, 8 };
if (_hash.IsSupersetOf(hash2)) {
Console.WriteLine("_hash contains 3 and 8");
}
或者,什么是等价的:
if (hash2.IsSubsetOf(_hash)) {
Console.WriteLine("_hash contains 3 and 8");
}
第三种解决方案:
一个List<HashSet<int>>
呢?因为现在,您可以将集合操作应用于列表的每个元素(这是一个哈希集)。
推荐阅读
- css - 如何让视图以特定的间隔填充?
- c++ - 错误 LNK2001:未解析的外部符号“公共:__thiscall CDboTSTAgency::CDboTSTAgency(void)”
- payment-gateway - 如何在 Global Payments PHP API 中访问过去交易的状态?
- sql - 是否可以在 SQL 中使用数组元素作为外键?
- sql - 一次对多条记录使用更新查询
- python - TF 模型是否将 pandas.Categorical() 转换的特征视为分类?
- python - 为什么装饰器需要包装器
- javascript - svg下的图像标签中的过滤器会降低图像的质量吗?
- typescript - 打字稿:接口联盟
- reactjs - 如何确保整个应用都可以使用 Google 注销按钮