我总是被告知java中的字符串是不可变的,除非你要使用字符串构建器类或字符串writter类。
看看我在网上找到的这个练习题,
给定一个字符串和一个非负int n,返回一个更大的字符串,它是原始字符串的n个副本。
stringTimes("Hi", 2) → "HiHi"
stringTimes("Hi", 3) → "HiHiHi"
stringTimes("Hi", 1) → "Hi"
并且解决方案出来了
解决方案:
public String stringTimes(String str, int n) {
String result = "";
for (int i=0; i<n; i++) {
result = result + str; // could use += here
}
return result;
}
正如您在解决方案中看到的那样,我们的第3行分配字符串,然后我们在for循环中更改它。这对我没有意义! (我以另一种方式回答了这个问题)一旦我看到这个解决方案,我知道我不得不问你们。
思考?我知道我在编程方面不是那么出色,但我之前没有见过这种类型的例子,所以我想我会分享。
答案 0 :(得分:4)
理解发生了什么的技巧如下:
result = result + str;
或其等价物
result += str;
Java编译器对此语法执行一个技巧 - 在场景后面,它生成以下代码:
result = result.concat(str);
变量result
两次参与此表达式 - 一次作为调用concat
方法的原始字符串,一次作为赋值的目标。赋值不会改变原始字符串,它会用String
提供的新不可变对象替换整个concat
对象。
也许更容易看出我们是否在代码中引入了额外的String
变量:
String temp = result.concat(str);
result = temp;
第一行执行后,您有两个String
个对象 - temp
,"HiHi"
和result
,仍为"Hi"
。执行第二行后,result
将替换为temp
,获取新值"HiHi"
。
答案 1 :(得分:2)
如果使用Eclipse,则可以创建断点并逐步运行它。您将找到&#34;结果&#34;的ID(在&#34; Variables&#34; View中找到它)。在java之后每次都改变了
result = result + str;
另一方面,如果你使用像
这样的StringBufferStringBuffer result = new StringBuffer("");
for(int i = 0; i < n; i++){
result.append(str);
}
结果的ID不会改变。
答案 2 :(得分:1)
String对象确实是不可变的。 result
不是String,它是对String对象的引用。在每次迭代中,都会创建一个新的String对象并将其分配给同一个引用。没有引用的旧对象最终会被垃圾收集器破坏。对于这样的简单示例,它是一种可能的解决方案。但是,在实际应用程序的每次迭代中创建一个新的String对象并不是一个明智的想法。