编程语言
首页 > 编程语言> > java – String.split()将原始的char数组保留在里面

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

作者:互联网

我注意到Java String会在其中重用char数组,以避免在诸如subString()之类的方法中为新的String实例创建新的char数组.为此,String中有几个取消发布的构造函数,接受一个char数组和两个int作为范围来构造一个String实例.

但直到今天我发现split还将重用原始String实例的char arr.现在我从一个文件中读取一个loooooong行,用“,”拆分它,并为实际用法剪切一个极限列.因为线的每个部分都秘密地拿着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,deep-copy,substring
来源: https://codeday.me/bug/20190901/1786075.html