【问题标题】:iterator remove still leaves the element in the set迭代器 remove 仍然将元素留在集合中
【发布时间】:2017-09-04 04:24:09
【问题描述】:

我有这个代码:

            for (Iterator<RuleConditionBl> iterator = ruleConditionBls.iterator(); iterator.hasNext();) {
                RuleConditionBl ruleConditionBl =  iterator.next();
                if (ruleConditionBl.equals(ruleCondition)) {
                    iterator.remove();
                }
            }
            if (ruleConditionBls.size() == 0)
            {
                countryToNonSplittedRules.remove(country);
            }

我在执行此行之前和之后看到ruleConditionBls.size == 1 iterator.remove();

我该如何解决这个问题?

【问题讨论】:

  • 您能否发布一个完整的可执行示例来演示这一点(即带有 main 方法的完整类?)
  • 是否进入 if 块?
  • 很可能与您的其他问题的原因相同:stackoverflow.com/questions/43300874/…。在将元素添加到集合后,您正在修改它。请不要问更多与同一问题相关的问题。相反,请提供一个完整的最小示例来重现它。
  • @JBNizet 但iterator.remove(); 是在运行时执行的,所以它绕过了原始计算的"hashkey"
  • @EladBenda2 没有。它使用当前的hashCode来查找元素所在的bucket,由于hashCode已经改变,所以没有找到。自己看吧:gist.github.com/jnizet/a98fbbcfe68ae27952043c01624e8eee

标签: java iterator set


【解决方案1】:

按照JB Nizet 的回答,我已经更改了我的代码,它现在可以工作了:

It uses the current hashCode to find the bucket where the element is located, and since the hashCode has changed, it doesn't find it.

   Set<RuleConditionBl> ruleConditionBls = countryToNonSplittedRules.get(country);
            if (ruleConditionBls != null) {

                final Set<RuleConditionBl> collect = ruleConditionBls.stream().filter(condition -> !condition.equals(ruleCondition)).collect(Collectors.toSet());
                if (collect.size() == 0)
                {
                    countryToNonSplittedRules.remove(country);
                }
                else
                {
                    countryToNonSplittedRules.put(country, collect);
                }
            }

【讨论】:

  • 我不太明白你在这里做什么。看来您正在尝试规避该错误而不是修复它。只是不要在将对象存储在 HashSet 中后对其进行修改。如果你这样做,你会到处都有错误。
猜你喜欢
  • 1970-01-01
  • 2017-08-17
  • 2018-01-08
  • 1970-01-01
  • 2021-05-05
  • 2018-06-09
  • 1970-01-01
  • 2012-05-13
相关资源
最近更新 更多