java我认为字符串是不可变的

时间:2018-05-08 00:33:08

标签: java string

我总是被告知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循环中更改它。这对我没有意义! (我以另一种方式回答了这个问题)一旦我看到这个解决方案,我知道我不得不问你们。

思考?我知道我在编程方面不是那么出色,但我之前没有见过这种类型的例子,所以我想我会分享。

3 个答案:

答案 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;

另一方面,如果你使用像

这样的StringBuffer
StringBuffer result = new StringBuffer("");
for(int i = 0; i < n; i++){
    result.append(str);
}

结果的ID不会改变。

答案 2 :(得分:1)

String对象确实是不可变的。 result不是String,它是对String对象的引用。在每次迭代中,都会创建一个新的String对象并将其分配给同一个引用。没有引用的旧对象最终会被垃圾收集器破坏。对于这样的简单示例,它是一种可能的解决方案。但是,在实际应用程序的每次迭代中创建一个新的String对象并不是一个明智的想法。