Java Collections API HashSet 移除方法

标签 java hashset

我在使用 Java Collections API 时遇到了这个问题。基本上,这是用于实现 Kruskal 算法以查找 MST 的支持方法。我创建了这个类来实现联合/查找算法。

我的问题是,因为我能够找到解决方法,所以有人知道为什么“union”方法中的 remove 方法无法始终如一地工作的任何原因。那是在运行时它会删除一些元素而不是其他元素。例如,我为涉及城市的任务实现了这个,它似乎不喜欢删除一些城市。特别是它反复偶然发现了几个不同的集合,但总是相同的。我想知道这是否是一个对象引用问题,即我是否在测试错误的东西,但我无法绕过它。

我知道我的其余工作是正确的,因为我能够用消除元素的循环替换它,并且算法完美执行。但是,可能性能稍差。

我想知道是否有人能看出错误。另外我应该注意,我从不同的类调用它,但是,调用是使用使用 find 方法检索的元素进行的。请注意,find 方法必须运行良好,因为只需更改 remove 方法即可使整个过程正常运行,即它正在查找并返回适当的对象。

谢谢

奥斯卡

/*
 * A constructor for creating a new object of this class.
 */
DisjointSets()
{
    underlying = new HashSet<HashSet<String>>();
}

/*
 * A method for adding a set to this DisjointSets object
 */
void add(HashSet<String> h)
{
    underlying.add(h);
}

/*
 * A method for finding an element in this DisjointSet object.
 */
HashSet<String> find(String s)
{
    // Check each set in the DisjointSets object
    for(HashSet<String> h: underlying)
    {
        if(h.contains(s))
        {
            return h;
        }
    }
    return null;
}

/*
 * A method for combining to subsets of the DisjointSets
 */
void union(HashSet<String> h1, HashSet<String> h2)
{
    System.out.print("CHECK ON DS\n");
    System.out.print("*********************\n");
    System.out.print("H1 is : { ");
    for (HashSet<String> n: underlying) 
    {
        System.out.print("Set is : { ");
        for (String h : n) 
        {
            System.out.print(h + " , ");
        }
        System.out.print("} \n ");
    }
    // Add the objects of h1 to h2
    // DOES NOT WORK CONSISTENTLY
            h1.addAll(h2);
    underlying.remove(h2);
}

我把它换成了

HashSet<HashSet<String>> temp = new HashSet<HashSet<String>>();
        for(HashSet<String> f: underlying)
        {
            if(f != h2)
            {
                temp.add(f);
            }
        }
        underlying = temp;

最佳答案

问题是,当您修改其中一个嵌套 HashSet 的内容时,您搞砸了外部 HashSet 的内部结构(因为嵌套 HashSet 的 hashCode() 已更改)。为了正确维护此集合,无论何时您想要修改其中一个嵌套的 HashSet,您都必须首先将其从外部 HashSet 中删除,然后重新添加(如有必要)。

(您并没有真正提供足够的代码来确定这是否真的是问题所在,但这是我最好的猜测)。

Set<Set<String>> outerSet = new HashSet<String>();
Set<String> innerSet = new HashSet<String>();

innerSet.add("foo");
outerSet.add(innerSet);

// *** BROKEN ***
innerSet.add("bar");       // <- adding element to innerSet changes result of innerSet.hashCode()
outerSet.remove(innerSet); // <- this may or may not work because outerSet is _broken_
// *** BROKEN ***

// *** CORRECT ***
outerSet.remove(innerSet);
innerSet.add("bar");
// now you can put innerSet back in outerSet if necessary

关于Java Collections API HashSet 移除方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5738574/

相关文章:

java - 导入斯坦福 nlp Intellij

java - 如何通过单击按钮来更改同一 Activity 中的布局?

java - 性能:JAVA排列

c# - 我可以将 HashSet<SomeEnumeration> 作为 HashSet<byte> 传递吗?

java - JAXB 对象工厂不包含 JAXBElement 创建方法

java - java中会在哪里创建对象

java - 以编程方式向 URL java 添加参数

java - 在 java 1.7.0_45 中向 HashMap 添加元素会导致 ArrayIndexOutofBoundsException

java - 在 Java 中查找两个大组之间差异的有效方法

Java : Implementing iterator for user-created HashSet class. next() 和 hasNext() 的语义?