我读到迭代 HashSet 是不好的做法。我应该先调用 .ToList() 吗?
我有一个名为 RegisteredItems 的项目集合。我不关心 RegisteredItems 中项目的顺序,只关心它们存在。
我对 RegisteredItems 执行两种类型的操作:
- 按属性查找并返回项目。
- 迭代集合并有副作用。
根据: 何时应该使用 HashSet
“迭代 HashSet 有点危险,因为这样做 对集合中的项目施加顺序。该命令实际上并不是一个 集合的属性。你不应该依赖它。如果订购 集合中的项目对您很重要,该集合不是 设置。”
我的集合将包含 50-100 个项目。我意识到这并不是一个很大的项目,但我仍然希望获得使用 HashSet 而不是 List 的回报。
我发现自己在寻找看到下面的代码,想知道该怎么做:
LayoutManager.Instance.RegisteredItems.ToList().ForEach( item => item.DoStuff() );
vs
foreach( var item in LayoutManager.Instance.RegisteredItems)
{
item.DoStuff();
}
RegisteredItems 过去返回一个 IList
,但现在它返回一个 HashSet,我觉得,如果我使用 HashSet 来提高效率,那就是然而,罗伯特的上述引用也让我对迭代它感到不安,
在这种情况下正确的选择是什么?
I have a collection of items called RegisteredItems. I do not care about the order of the items in RegisteredItems, only that they exist.
I perform two types of operations on RegisteredItems:
- Find and return item by property.
- Iterate over collection and have side-effect.
According to: When should I use the HashSet<T> type? Robert R. says,
"It's somewhat dangerous to iterate over a HashSet because doing so
imposes an order on the items in the set. That order is not really a
property of the set. You should not rely on it. If ordering of the
items in a collection is important to you, that collection isn't a
set."
There are some scenarios where my collection would contain 50-100 items. I realize this is not a large amount of items, but I was still hoping to reap the rewards of using a HashSet instead of List.
I have found myself looking at the following code and wondering what to do:
LayoutManager.Instance.RegisteredItems.ToList().ForEach( item => item.DoStuff() );
vs
foreach( var item in LayoutManager.Instance.RegisteredItems)
{
item.DoStuff();
}
RegisteredItems used to return an IList<T>
, but now it returns a HashSet. I felt that, if I was using HashSet for efficiency, it would be improper to cast it as a List. Yet, the above quote from Robert leaves me feeling uneasy about iterating over it, as well.
What's the right call in this scenario? Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您不关心顺序,请使用 HashSet<>。引用是关于使用 HashSet<>当你担心秩序时就会很危险。如果您多次运行此代码,并且以不同的顺序操作项目,您会在意吗?如果没有,那你就没事了。如果是,则不要使用 HashSet<>。先任意转换为List并不能真正解决问题。
我不确定,但我怀疑 .ToList() 会迭代 HashSet<>为此,现在您需要两次遍历该集合。
不要过早优化。如果你只有 100 个项目,只需使用 HashSet<> 即可。并继续前进。如果您开始关心顺序,请将其更改为 List<>然后将其用作任何地方的列表。
If you don't care about order, use a HashSet<>. The quote is about using HashSet<> being dangerous when you're worried about order. If you run this code multiple times, and the items are operated on in different order, will you care? If not, then you're fine. If yes, then don't use a HashSet<>. Arbitrarily converting to a List first doesn't really solve the problem.
And I'm not certain, but I suspect that .ToList() will iterate over the HashSet<> to do that, so, now you're walking the collection twice.
Don't prematurely optimize. If you only have 100 items, just use a HashSet<> and move on. If you start caring about order, change it to a List<> then and use it as a list everwhere.
如果您真的不关心顺序并且知道哈希集中不能有重复项(这就是您想要的),请继续使用哈希集。
If you really don't care about order and you know that you can't have duplicate in your hashset (and it's what you want), go ahead use hashset.
在引用的问题中,我认为他是说,如果您迭代一个集合,您可以很容易地欺骗自己认为这些项目是按一定顺序排列的。例如,很容易以不同的方式处理第一个迭代项,但不能保证它仍然是第一个迭代项。
只要记住这一点,并考虑 Set 无序,迭代它就可以了。
In the quoted question, I think he's saying that if you iterate over a Set, you can easily trick yourself into thinking that the items are in a certain order. For example, it'd be easy to treat the first iterated item differently, but you aren't guaranteed that will remain the first iterated item.
As long as you keep this in mind, and consider the Set unordered, iterating over it is fine.