Java中Iterator.remove的C#等价实现及代码迁移问题
解决Java Iterator.remove()的C#等价实现问题
嘿,我来帮你搞定这个Java到C#的迁移问题!首先得明确:C#里的IEnumerator<T>并没有直接对应Java Iterator.remove()的方法——因为C#的常规枚举器不允许在迭代过程中修改集合(否则会抛出InvalidOperationException)。不过我们有几种安全的方式来实现和原Java代码相同的逻辑:
方法1:倒序for循环(最直接安全的方式)
因为原代码是在遍历集合时删除符合条件的元素,同时还要调用highU.decreaseCount(),倒序遍历List可以避免删除元素后索引错乱的问题,代码如下:
foreach (List<ItemNY> level in highU.getLevels()) { // 倒序遍历,删除元素不会影响未遍历的索引 for (int i = level.Count - 1; i >= 0; i--) { ItemNY c = level[i]; // 这里放你原来的业务代码... if (c.getU() < min) { level.RemoveAt(i); // 删除当前元素 highU.decreaseCount(); } } }
方法2:使用临时集合记录要删除的元素
如果你更倾向于类似原Java的迭代风格,可以先遍历收集所有需要删除的元素,再批量删除(不过这种方式会多一次遍历,适合元素数量不多的场景):
foreach (List<ItemNY> level in highU.getLevels()) { List<ItemNY> itemsToRemove = new List<ItemNY>(); foreach (ItemNY c in level) { // 业务代码... if (c.getU() < min) { itemsToRemove.Add(c); } } // 批量删除并更新计数 foreach (ItemNY item in itemsToRemove) { level.Remove(item); highU.decreaseCount(); } }
为什么不直接用IEnumerator?
你原来尝试的using (IEnumerator<ItemNY> iterItemset = level.GetEnumerator())这条路走不通,因为C#的List<T>.Enumerator是一个结构体,它没有Remove方法,而且一旦你在迭代过程中修改集合(比如调用level.Remove()),枚举器就会失效,下次调用MoveNext()会直接抛出异常。
所以上面两种方法里,倒序for循环是最贴近原Java代码逻辑且性能最优的选择。
内容的提问来源于stack exchange,提问作者Reza Hatami
相关产品推荐
相关产品推荐

