迭代Java Set时修改元素

时间:2014-08-06 23:57:30

标签: java

这里是Java的新手。我来自Python。关于在迭代Java集时删除或添加元素的问题,也有类似的问题。我想知道的是修改Set中包含的元素。例如,["apple", "orange"]["iapple", "iorange"]。另外,我想在适当的位置进行,即不创建另一个集合,并在迭代时将修改后的元素放入新集合中。

显然,简单的for循环不起作用,如下所示:

import java.util.Arrays;
import java.util.Set;
import java.util.HashSet;

class Test {
    public static void main (String[] args) {
        Set<String> strs = new HashSet<String>(Arrays.asList("apple", "orange"));

        for (String str : strs) {
            str = "i" + str;
        }
    }
}

4 个答案:

答案 0 :(得分:2)

您无法修改java中的String,它们是不可变的。 虽然理论上可以在Set中使用可变元素并将它们变异,但如果变异影响哈希码(和等于),则它是terrible idea

因此,对于您的具体问题的答案是否定的,您不能在String中改变Set值而不删除然后向Set添加条目。

答案 1 :(得分:2)

您所写的问题是您没有对计算值做任何事情。 for-each循环将str的值设置为每个元素。在for循环中,您正在更改str的值,但不会对其执行任何其他操作。

这在链表或任何支持索引的数据结构中很容易做到,但是使用set可能会很棘手。只删除旧元素并添加新元素可能会搞砸迭代,特别是因为您正在处理哈希集。

执行此操作的一种简单方法是转换为列表并返回:

class Test {
public static void main (String[] args) {
    Set<String> strs = new HashSet<String>(Arrays.asList("apple", "orange"));

    //Convert to list
    LinkedList<String> strsList = new LinkedList<String>();
    strsList.addAll(strs);

    //Do modification
    for (int i = 0; i < strsList.size(); i++) {
        String str = strsList.get(i);
        strsList.set(i,"i" + str);
    }

    //Convert back to set
    strs.clear();
    strs.addAll(strsList);
    }
}

这显然比你预期的要多一些,但如果大众更换是你预期的行为,那么可能不会使用一套。 我有兴趣看看其他答案也会出现。

答案 2 :(得分:0)

问题是在for循环中,str只是对String的引用。引用在重新分配时不会更改它引用的实际对象。另外,字符串无论如何都是不可变的,因此调用它们上的任何方法都会为你提供一个新的String而不是修改原始字符串。你想要做的是将所有新的字符串存储在某处,取出旧的字符串,然后添加新的字符串。

编辑:我原来的代码会抛出一个ConcurrentModificationException。

答案 3 :(得分:0)

解决问题的方法有3个问题。

1st - 您在迭代时无法修改Set的内容。您需要使用新值创建一个新集。

&#34;但是我没有修改集合,我正在修改其中的对象&#34;,这会导致问题二

第二 - 在您的代码中,您正在修改对字符串的引用,而不是字符串本身。 要修改字符串,您需要在其上调用方法,例如string.changeTo("this"),或修改字段string.value = "new value"

导致问题三。

第3名 - 字符串是不可变的。当你构造一个字符串时,比如new String("hello"),你就不能进一步修改它的内在价值。

解决方案

第一个选项是更简单的选项,创建一个新的设置。

第二个选项是使用字符串构建器而不是字符串,这些字符串是可变字符串创建者/占位符。

http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html