从HashSet中删除元素

时间:2013-12-01 12:17:47

标签: java hashset

我有代码:

System.out.println("before: " + clusters.size());

        Iterator it = clusters.iterator();
        while (it.hasNext()) {
            Set<Place> set = (Set<Place>) it.next();
            if (set == max2) {
                System.out
                        .println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
                it.remove();
                break;
            }
        }

        System.out.println("after: " + clusters.size());

我这样做是因为clusters.remove(max2)返回false。 现在打印

before: 96
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
after: 96

怎么可能?

2 个答案:

答案 0 :(得分:2)

虽然您的代码应该(直观地)起作用,但您的设置方式受到了限制。集合的散列是其项目的所有散列的总和,散列集的项目必须具有一致的散列,或者在查找期间无法找到它们。你正在使用一组集合,我相信你已经修改了它们在集合中的子集,所以它现在找不到它们来删除它们。这是未定义的行为区域,因此当针对标准库的不同版本和实现进行编译时,您可能会发现它的行为有所不同。

你最好使用key-&gt; set的地图。一般来说,请记住,在将一个项目添加到集合中(或将其用作地图中的键)之后,您应该不做任何会改变其散列的内容(当然,这适用于HashSet和{{1 s,这是最常见的。对于其他类型,请遵循其文档中给出的特定规则,但它通常归结为:一旦添加就不要更改它。)

编辑:似乎KEYSER在评论中用他的信息打败了我。哦,好吧。

另外,关于使用==而不是HashMap的注释是有效的,但如果您知道该对象肯定是完全相同的引用那么您的代码是好的(而且更快!)。从您看到的日志语句中可以看出这种情况。

答案 1 :(得分:0)

关于Iterator.remove():
从底层集合中移除迭代器返回的最后一个元素(可选操作)。每次调用next时,只能调用一次此方法。如果在迭代正在进行中以除了调用此方法之外的任何方式修改基础集合,则未指定迭代器的行为。