Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java集合API哈希集删除方法_Java_Hashset - Fatal编程技术网

Java集合API哈希集删除方法

Java集合API哈希集删除方法,java,hashset,Java,Hashset,我在使用Java Collections API时遇到了这个问题。基本上,这是Kruskal查找MST算法实现的支持方法。我创建这个类是为了实现union/find算法 我的问题是,当我能够找到一种解决方法时,有人知道为什么“联合”方法中的remove方法不能一直工作吗。也就是说,在运行时,它将删除一些元素,而不是其他元素。例如,我为一项涉及城市的任务实施了这项任务,它似乎不像移除一些城市。特别是,它反复发现了几个不同的场景,但总是相同的场景。我想知道这是否是一个对象引用问题,即我是否测试了错误

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

我的问题是,当我能够找到一种解决方法时,有人知道为什么“联合”方法中的remove方法不能一直工作吗。也就是说,在运行时,它将删除一些元素,而不是其他元素。例如,我为一项涉及城市的任务实施了这项任务,它似乎不像移除一些城市。特别是,它反复发现了几个不同的场景,但总是相同的场景。我想知道这是否是一个对象引用问题,即我是否测试了错误的东西,但我无法回避它

我知道我的其余工作是正确的,因为我能够用一个消除元素的循环来替换它,并且算法执行得非常完美。不过,性能可能稍差一些

我想知道是否有人能看出一个错误。我还应该注意,我从不同的类调用了它,但是,调用是使用find方法检索的元素进行的。请注意,find方法必须很好地工作,因为简单地修改remove方法就可以完成整个工作,即查找并返回适当的对象

谢谢

奥斯卡

/*
*用于创建此类的新对象的构造函数。
*/
不相交集()
{
底层=新HashSet();
}
/*
*将集合添加到此DisjointSets对象的方法
*/
无效添加(哈希集h)
{
添加(h);
}
/*
*用于在此不相交集对象中查找元素的方法。
*/
哈希集查找(字符串s)
{
//检查DisjointSets对象中的每个集合
for(哈希集h:基础)
{
如果(h.包含)
{
返回h;
}
}
返回null;
}
/*
*不相交集子集的一种组合方法
*/
无效并集(哈希集h1、哈希集h2)
{
System.out.print(“检查DS\n”);
系统输出打印(“***************************\n”);
System.out.print(“H1为:{”);
for(哈希集n:基础)
{
System.out.print(“设置为:{”);
for(字符串h:n)
{
系统输出打印(h+“,”);
}
System.out.print(“}\n”);
}
//将h1的对象添加到h2
//不能始终如一地工作
h1.addAll(h2);
移除(h2);
}
}

我把它换成了

HashSet<HashSet<String>> temp = new HashSet<HashSet<String>>();
        for(HashSet<String> f: underlying)
        {
            if(f != h2)
            {
                temp.add(f);
            }
        }
        underlying = temp;
HashSet temp=new HashSet();
for(哈希集f:基础)
{
如果(f!=h2)
{
温度添加(f);
}
}
基础=温度;

问题在于,当您修改其中一个嵌套哈希集的内容时,您会破坏外部哈希集的内部结构(因为嵌套哈希集的hashCode()已更改)。为了正确维护此集合,每当您想要修改其中一个嵌套哈希集时,必须首先将其从外部哈希集中删除,然后重新添加(如果需要)

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

Set outerSet=new HashSet();
Set innerSet=new HashSet();
innerSet.add(“foo”);
添加(内部集合);
//***破损***

innerSet.add(“bar”);// 问题是,当您修改其中一个嵌套哈希集的内容时,会破坏外部哈希集的内部结构(因为嵌套哈希集的hashCode()已更改)。为了正确维护此集合,每当您想要修改其中一个嵌套哈希集时,必须首先将其从外部哈希集中删除,然后重新添加(如果需要)

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

Set outerSet=new HashSet();
Set innerSet=new HashSet();
innerSet.add(“foo”);
添加(内部集合);
//***破损***

innerSet.add(“bar”);// 根据@jtahlborn的回答,合同上说

返回此文件的哈希代码值 设置定义了集合的哈希代码 为的哈希代码之和 集合中的元素。这确保 s1.等于(s2)意味着 s1.hashCode()==s2.hashCode()用于任何 两套s1和s2,如制造商要求 Object.hashCode的总合同

此实现列举了超过 集合,调用hashCode方法 在集合中的每个元素上,以及 把结果加起来

用于演示@jtahlborn答案的代码(正确)

import java.util.HashSet;
导入java.util.Set;
公共类TestHashSetHashCode{
公共静态void main(字符串[]args)
{
Set strings=newhashset();
字符串。添加(“一”);
字符串。添加(“两个”);
字符串。添加(“三”);
字符串。添加(“四”);
字符串。添加(“五”);
Set test=新的HashSet();
System.out.println(“Code”+test.hashCode());
用于(字符串s:字符串){
测试。添加(s);
System.out.println(“Code”+test.hashCode());
}
}
}
输出

Code 0 Code 115276 Code 3258622 Code 3368804 Code 113708290 Code 116857384 代码0 代码115276 代码3258622 代码3368804 代码113708290 代码116857384
还有一个理由需要添加到列表中,以便尽可能利用不可变的集合。

根据@jtahlborn的回答,该合同称

返回此文件的哈希代码值 设置定义了集合的哈希代码 为的哈希代码之和 集合中的元素。这确保 s1.等于(s2)意味着 s1.hashCode()==s2.hashCode()用于任何 两套s1和s2,如制造商要求 Object.hashCode的总合同

此实现列举了超过 集合,调用hashCode方法 在集合中的每个元素上,以及 把结果加起来

用于演示@jtahlborn答案的代码(正确)

import java.util.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
import java.util.HashSet;
import java.util.Set;


public class TestHashSetHashCode {

  public static void main(String[] args)
  {
    Set<String> strings = new HashSet<String>();
    strings.add("one");
    strings.add("two");
    strings.add("three");
    strings.add("four");
    strings.add("five");
    Set<String> test = new HashSet<String>();
    System.out.println("Code "+test.hashCode());
    for (String s : strings) {
      test.add(s);
      System.out.println("Code "+test.hashCode());
    }
  }
}
Code 0 Code 115276 Code 3258622 Code 3368804 Code 113708290 Code 116857384