这里是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;
}
}
}
答案 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