java - String.split() 将保留原始的 char 数组在里面

标签 java string split substring deep-copy

我注意到 Java String 将在其中重用 char 数组,以避免在 subString() 等方法中为新的 String 实例创建新的 char 数组。为此,String 中有几个 unpublish 构造函数,接受一个 char 数组和两个 int 作为范围来构造一个 String 实例。

但是直到今天我发现split也会重用原始String实例的char arr。现在我从一个文件中读取了一个 loooooong 行,用“,”将其拆分并剪切了一个非常有限的列以供实际使用。因为该行的每一部分都 secret 持有 looooong char 数组的引用,所以我很快得到了一个 OOO。

这里是示例代码:

ArrayList<String> test = new ArrayList<String>(3000000);
BufferedReader origReader = new BufferedReader(new FileReader(new File(
        "G:\\filewithlongline.txt")));
String line = origReader.readLine();
int i = 0;
while ((line = origReader.readLine()) != null) {
    String name = line.split(',')[0];
    test.add(name);
    i++;
    if (i % 100000 == 0) {
        System.out.println(name);
    }
}
System.out.println(test.size());

JDK 中是否有任何标准方法来确保吐出的每个 String 实例都是“真正的深拷贝”而不是“浅拷贝”?

现在我正在使用一个非常丑陋的解决方法来强制创建一个新的 String 实例:

ArrayList<String> test = new ArrayList<String>(3000000);
BufferedReader origReader = new BufferedReader(new FileReader(new File(
        "G:\\filewithlongline.txt")));
String line = origReader.readLine();
int i = 0;
while ((line = origReader.readLine()) != null) {
    String name = line.split(',')[0]+"  ".trim(); // force creating a String instance
    test.add(name);
    i++;
    if (i % 100000 == 0) {
        System.out.println(name);
    }
}
System.out.println(test.size());

最佳答案

最简单的方法是直接创建一个新的String。这是极少数的好主意之一。

String name = new String(line.split(",")[0]); // note the use of ","

另一种方法是自己解析文件。

do {
    StringBuilder name = new StringBuilder();
    int ch;
    while((ch = origReader.read()) >= 0 && ch != ',' && ch >= ' ') {
       name.append((char) ch);
    }
    test.add(name.toString());
} while(origReader.readLine() != null);

关于java - String.split() 将保留原始的 char 数组在里面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12238263/

相关文章:

MySQL将同一表中不同列的多值字符串拆分到新表中

python - 如何在特定字符之前拆分字符串?

java - DBRider 在新测试类运行之前没有清理数据,我该如何解决这个问题?

java - Flyway 无法检测到新的迁移文件

java - 非平凡的推土机映射

c++ - 如何在字符串中添加换行符?

java - split ("[^0-9a-zA-Z]+")在结果中显示空字符串

java - 如何在Java中为工具栏添加窗口API?

python-3.x - 在Python中将特定的中文标点符号替换为相应的英文标点符号

java - 分割字符串java返回值