hashset 相关问题

HashSet封装了允许比较集合中元素的操作。 HashSets经常用于确定集合中的重叠元素和唯一元素。


我的 HashSet 在修改后存储了重复的对象

我是一名编程导师。昨天,我试图通过一些测试用例向我的学生解释 HashSet。当然,HashSet允许修改包含的对象,但它可能会导致不一致问题......

回答 1 投票 0

Set.of(E... elements) - 它使用哪个 Set 实现?它与 new HashSet<>() 有何关系?

我想问-有什么区别 Set set1 = new HashSet<>() {{ 添加(“一个”); 添加(“b”); 添加(“c”); }} 和 设置<

回答 2 投票 0

HashSet:为什么 valueType.Equals(Object) 这么慢

有这个方法: public void RunFD(目标文件Obj, ISet访问) { if (!visited.Add(fileObj)) 返回; if (fileObj 是 IEnumerable enumerablFileObj ) { foreach (... 有了这个方法: public void RunFD(object fileObj, ISet<object> visited) { if (!visited.Add(fileObj)) return; if (fileObj is IEnumerable enumerablFileObj ) { foreach (var aFileObj in enumerablFileObj.OfType<object>()) { RunFD(aFileObj , visited); } } else { AddToFolder(fileObj); } } fileObj 是一个简单的对象,可以包含字符串或自定义对象。可能会出现Parent1 -> child -> Parent1的场景,因此使用名为visited的HashSet。这里,Parent1 指的是与另一个 Parent1 完全相同的实例。 尽管此方法按预期运行,但我注意到执行时间相当长。令人惊讶的是,大部分执行时间都花在了visited.Add(fileObj)上。 在执行过程中,观察到最耗时的操作是HashSet.AddIfNotPresent -> ObjectEqualityComparer.Equals -> ValueType.Equals(Object),它占了我的方法总执行时间的95%。 我很困惑,因为我预计 HashSet 的时间复杂度通常为 O(1),仅检查引用对象是否与另一个相同(这符合我的要求)。 考虑到我有多种类型的 fileObj 类,我是否应该为所有这些类重写 Equals 方法?有没有更有效的方法来检查对象是否相同? 我尝试寻找另一种解决方案,但唯一出现的解决方案是重载对象的 Equals 和 GetHashCode 方法。然而,这是非常痛苦的,因为我有很多可能的对象用于此方法.. 为什么 valueType.Equals(Object) 这么慢 需要注意的潜在问题之一是ValueType.Equals可以使用反射。如果值类型不覆盖相等成员,并且例如包含引用类型字段/属性(请参阅此 github 问题中的列表),它将使用反射来执行操作: // if there are no GC references in this object we can avoid reflection // and do a fast memcmp if (CanCompareBitsOrUseFastGetHashCode(RuntimeHelpers.GetMethodTable(obj))) // MethodTable kept alive by access to object below { return //... } FieldInfo[] thisFields = GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int i = 0; i < thisFields.Length; i++) { object? thisResult = thisFields[i].GetValue(this); object? thatResult = thisFields[i].GetValue(obj); // ... } 这显然是成本相对较高的操作。 缓解措施 - 在结构体上定义自定义 GetHashcode 和 Equals 或为集合提供自定义 IEqualityComparer 比较器。 另一个值得研究的点是调用 Equals 的时间。但这需要一个完整的再现器。 O(1)是通过“良好”的哈希函数实现的,这会导致很少发生冲突,这可能不是您的数据的情况(或者只是您的数据有很多重复项)。 如果您只需要检查引用相等性,请使用使用 ReferenceEquals 的自定义相等比较器: public class ReferenceEqualityComparer<T> : IEqualityComparer<T> where T : class { public static IEqualityComparer<T> Default { get {return new ReferenceEqualityComparer<T>();}} public bool Equals(T x, T y){ return ReferenceEquals(x, y); } public int GetHashCode(T obj) { return RuntimeHelpers.GetHashCode(obj); } } var visited = new HashSet<object>(ReferenceEqualityComparer<object>.Default);

回答 2 投票 0

C#:HashSet:为什么 valueType.Equals(Object) 这么慢

有这个方法: public void RunFD(目标文件Obj, ISet访问) { if (!visited.Add(fileObj)) 返回; if (fileObj 是 IEnumerable enumerablFileObj ) { foreach (... 有了这个方法: public void RunFD(object fileObj, ISet<object> visited) { if (!visited.Add(fileObj)) return; if (fileObj is IEnumerable enumerablFileObj ) { foreach (var aFileObj in enumerablFileObj.OfType<object>()) { RunFD(aFileObj , visited); } } else { AddToFolder(fileObj); } } fileObj 是一个简单的对象,可以包含字符串或自定义对象。可能会出现Parent1 -> child -> Parent1的场景,因此使用名为visited的HashSet。这里,Parent1 指的是与另一个 Parent1 完全相同的实例。 尽管此方法按预期运行,但我注意到执行时间相当长。令人惊讶的是,大部分执行时间都花在了visited.Add(fileObj)上。 在执行过程中,观察到最耗时的操作是HashSet.AddIfNotPresent -> ObjectEqualityComparer.Equals -> ValueType.Equals(Object),它占了我的方法总执行时间的95%。 我很困惑,因为我预计 HashSet 的时间复杂度一般为 O(1),仅检查引用对象是否与另一个相同(这符合我的要求)。 考虑到我有多种类型的 fileObj 类,我是否应该为所有这些类重写 Equals 方法?有没有更有效的方法来检查对象是否相同? 我尝试寻找另一种解决方案,但唯一出现的解决方案是重载对象的 Equals 和 GetHashCode 方法。然而,这是非常痛苦的,因为我有很多可能的对象用于此方法.. 如果您只需要检查引用相等性,请使用使用 ReferenceEquals 的自定义相等比较器: public class ReferenceEqualityComparer<T> : IEqualityComparer<T> where T : class { public static IEqualityComparer<T> Default { get {return new ReferenceEqualityComparer<T>();}} public bool Equals(T x, T y){ return ReferenceEquals(x, y); } public int GetHashCode(T obj) { return RuntimeHelpers.GetHashCode(obj); } } var visited = new HashSet<object>(ReferenceEqualityComparer<object>.Default);

回答 1 投票 0

无法在java中打印简单的HashSet<int[]>元素[重复]

我尝试在 java 20 中打印简单的 HashSet 但没有成功,我在这里缺少什么? 公共静态无效主(字符串[] args){ int[] a1 = {1,3,6,8,10,11,14,17,21}; int[] a2 = {2,4,8,9,12,14,15}...

回答 1 投票 0

使用方法引用与 HashSet 进行复制

我想知道我的List是否有重复的元素。 我看过下面的方法: 公共静态布尔areAllUnique(列表列表){ 返回 list.stream().allMatch(new

回答 2 投票 0

HashSet 如何比较元素是否相等?

我有一个 IComparable 类: 公共类a:IComparable { 公共 int Id { 得到;放; } 公共字符串名称{获取;放; } 公共a(int id) { 这个.Id = id; }

回答 5 投票 0

在c#中使用运算符[..]从HashSet获取数组

这些是范围运算符和索引器吗?我从未见过它们像这样使用[..h]。 此代码中的第 6 行: 公共静态无效主要(字符串[]参数) { int[] a ={1,2,3,4,5,6,7,8,9}; 哈希集 这些是范围运算符和索引器吗?我从来没有见过它们这样使用[..h]。 此代码中的第 6 行: public static void Main(string[] args) { int[] a ={1,2,3,4,5,6,7,8,9}; HashSet<int> h=new(a); /// do somethings on HashSet WriteArray([..h]); } static void WriteArray(int[] a) { foreach(var n in a) { Console.Write($"{n} "); } } [..h]中使用什么运算符? 您能推荐一个参考资料来研究这些运算符或使用的方法吗? [..h]是一个集合表达式,基本上是创建集合、数组和跨度的简洁语法。 [和]里面的东西是集合的元素,例如 List<int> x = [1,2,3]; // basically: // var x = new List<int> { 1,2,3 }; 由于这是传递给需要 int[] 的参数,因此 [..h] 代表 int[]。那么这个数组包含什么?什么是..h?在集合表达式中, .. 可以作为另一个集合的前缀,以“spread”该集合的元素。 由于 h 包含数字 1 到 9,所以这基本上是 [1,2,3,4,5,6,7,8,9],不过由于 HashSet 没有排序,因此元素的顺序可能不同。 通常,当您想要将其他元素/集合放入集合表达式中时,使用 ..,如文档中的示例所示: string[] vowels = ["a", "e", "i", "o", "u"]; string[] consonants = ["b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "z"]; string[] alphabet = [.. vowels, .. consonants, "y"]; 所以 [..h] 是集合表达式的一种相当奇怪的用法。使用 h.ToArray() 来代替会更具可读性。

回答 1 投票 0

删除集合[重复项]中的重复项

如何避免在 Set 中插入重复元素?如果我有: Set user=new HashSet<>(); 用户 user1=新用户("11","标记",null,&...

回答 1 投票 0

C# 根据哈希集抓取表的子集 if Ints

我有一个 Order 和 OrderMaster 表,首先我查询 Master 表,然后从该表创建 Int 列的哈希集。最后,我想获取具有这些值的所有订单。当我...

回答 1 投票 0

std::std::unordered_set 中的距离

我想借助HashSet来解决这个问题。当我尝试发布解决方案时,在第二种情况下失败,答案为 [2,0] 然而,当我尝试在 IDE 上做同样的事情时,它...

回答 1 投票 0

为什么我的 HashSet 在 ORMLite 中序列化不正确?序列化时的尺寸似乎有误

我将应用程序中的字段保存为哈希集,定义如下: @DatabaseField(dataType = DataType.SERIALIZABLE) 私有 HashSet allUsers; 有些设备偶尔会...

回答 1 投票 0

插入或修改HashSet内容

结构A { 数据:T, 计数:使用, } 结构 B { 设置:HashSet>, } 实现 B { fn add(&mut self, data: T) -> &A ...

回答 1 投票 0

为什么 HashSet 的内部实现会创建虚拟对象作为值插入到 HashMap 中而不是插入空值?

HashSet 是使用 HashMap 实现的,当我们向 HashSet 添加任何内容(比如 e1)时,如果集合中不存在 e1,它会在内部将 (e1,new Object()) 添加到 HashMap 中。我的问题是为什么他们会这样

回答 4 投票 0

为什么在Contains期间没有调用GetHashCode?

直到今天我的理解是 HashSet 在 Contains 中使用 GetHashCode。这也是说的,例如这里。 我写了一些 IEqualityComparer: 公共类 MyComparer :IEqualityComparer 直到今天我的理解是 HashSet 在 GetHashCode 中使用 Contains。这也是说的,例如这里。 我写了一点IEqualityComparer: public class MyComparer : IEqualityComparer<string> { public bool Equals(string? a, string? b) { return a == b; } public int GetHashCode(string a) { throw new NotImplementedException(); } } 并像这样使用它: public void TestMyComparer() { var x = new HashSet<string>(new []{ "hello", "world" }); bool helloInside = x.Contains("hello", new MyComparer()); } 但是 TestMyComparer 并没有像我预期的那样抛出 NotImplementedException 。相反,它返回 true。 为什么? 如果您想在 HashSet.Contains 中使用自定义比较器,请将其传递给 构造函数。 var x = new HashSet<string>(new MyComparer()); x.Add("hello"); x.Add("world"); bool helloInside = x.Contains("hello"); 现在使用GetHashCode,因为您使用基于集合的集合,而不是Enumerable.Contains,它只是枚举所有项目并将它们与Equals进行比较。

回答 1 投票 0

HashSet<T>与Dictionary<K, V>w.r.t搜索时间来查找项目是否存在

HashSet t = new HashSet(); // 添加 1000 万个项目 字典 t = 新字典(); // 添加 1000 万个项目。 谁的 .Contains 方法返回得更快? ...

回答 5 投票 0

用于推送到其成员被引用的向量的 Rust 所有权

TL;DR:我想要一个不可变元素的向量,它允许对其成员进行短暂的不可变引用,同时能够推送它。 我正在制作一个用于精确算术的板条箱,用作 d...

回答 1 投票 0

更改 JAVA 中 HashSet 内对象的属性值时出现问题

我正在学习java并面临一个非常奇怪的问题,我认为用我的代码来解释这个更容易 这是我的课: 类节点 { 私有 int 值; 公共节点(int val) { ...

回答 2 投票 0

检查 ReadOnlyMemory<char> 是否包含在 C# 中的哈希集中的有效方法

我一直在寻找一些有效且精确的方法来检查 C# 中的 ReadOnlyMemory 是否包含在 ReadOnlyMemory 的哈希集中或任何其他集合中。 我看到了一些要转换的建议...

回答 1 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.