Java String如何在内部删除所有非数字工作?

时间:2013-12-16 07:57:03

标签: java string immutability

由于字符串是不可变的,我必须按如下方式编写,以从str中删除所有非字母数字。

void test(String str) {
    str = str.replaceAll("[^a-zA-Z0-9\\s]", "").toLowerCase();
    System.out.println("\n" +str);
    }

我无法理解的是,如何通过重新分配到str来实现它?

由于String是不可变的,我理解如果我将它分配给一个新的String newString,它们指出两个不同的对象str和newString。 它,原始字符串指向str和修改后的字符串指向ot newStr,它有两个不同的不可变字符串。这对我来说没问题。

void test(String str) {
            String newStr = str.replaceAll("[^a-zA-Z0-9\\s]", "").toLowerCase();
    System.out.println("\n" +newStr);
    }

但是如何重新分配到同一个str对象呢?根据我的理解,它不应该工作,因为不可变的str不能修改,所以修改的str的结果不能存储在不可变的str中。

void test(String str) {
      // this shouldn't be working based on my understanding. But it works. Why?
    str = str.replaceAll("[^a-zA-Z0-9\\s]", "").toLowerCase();
    System.out.println("\n" +str);
    }

正如您所见,下面的图像中,string1和string2指向堆中的同一个String对象。你能澄清一下它在内部是如何运作的吗?

3 个答案:

答案 0 :(得分:2)

您没有分配到同一个str对象。

看一下replaceAll等方法,你会看到它们返回String,这是一个替换所有方法创建的新String对象。

因此str=str.replaceAll()String获取str引用,在replaceAll()中调用StringreplaceAll进程this然后返回一个新的String对象,其中包含该处理的结果。然后将其分配回原始参考。

答案 1 :(得分:2)

您需要了解参考:str是对您记忆中某个区域的引用。发生了什么,Java运行时创建一个新的内存区域,其中包含删除所有字符的字符串,然后将“{1}”“指向”新的内存区域。

这与修改str已指向的内存区域不同。

“Immutability”意味着变量指向的内存区域无法修改。内容是固定的。要“修改”它,必须复制,修改内存然后重新分配。

“Mutable”对象可以修改内存中的数据,而无需将旧数据复制到新的内存区域。


顺便说一句,在我们的示例中,字符串甚至被复制了两次!

第一次,复制字符串:

str

然后由

创建另一个副本
replaceAll("[^a-zA-Z0-9\\s]", "")

然后最终分配给您的变量。

您的代码因此等于以下内容:

toLowerCase()

答案 2 :(得分:0)

您需要了解在Java中,变量不是对象;变量引用到对象。

因此,str不是String对象,它是对String对象的引用。 “不可变”意味着变量所指的对象的内容不能改变;这并不意味着变量本身不能更改为引用不同的对象。

您正在使str指向不同的String对象;即String返回的新str.replaceAll对象。