在 Java 中拆分字符串的最有效方法
Most efficient way of splitting String in Java
为了这个问题,假设我有一个 String
,其中包含值 Two;.Three;.Four
(依此类推),但元素由 ;.
分隔。
现在我知道有多种拆分字符串的方法,例如 split()
和 StringTokenizer
(速度更快且效果很好)但我的输入文件约为 1GB 并且我正在寻找比 StringTokenizer
.
稍微更有效的东西
经过一些研究,我发现 indexOf
和 substring
非常有效,但示例只有单个分隔符或结果仅返回单个 word/element.
示例代码使用 indexOf
和 substring
:
String s = "quick,brown,fox,jumps,over,the,lazy,dog";
int from = s.indexOf(',');
int to = s.indexOf(',', from+1);
String brown = s.substring(from+1, to);
以上内容适用于打印 brown
,但我如何使用 indexOf
和 substring
拆分具有多个分隔符的行并显示所有项目,如下所示。
预期输出
Two
Three
Four
....and so on
如果你想要极致的效率,我根本不会使用Strings
,更不用说拆分它们了。我会做编译器做的事情:一次处理一个字符的文件。使用具有较大缓冲区大小的 BufferedReader
,例如 128kb,并一次读取 char
,将它们累积成 StringBuilder
,直到获得 ;
或行终止符.
StringTokenizer
比 StringBuilder
.
快
public static void main(String[] args) {
String str = "This is String , split by StringTokenizer, created by me";
StringTokenizer st = new StringTokenizer(str);
System.out.println("---- Split by space ------");
while (st.hasMoreElements()) {
System.out.println(st.nextElement());
}
System.out.println("---- Split by comma ',' ------");
StringTokenizer st2 = new StringTokenizer(str, ",");
while (st2.hasMoreElements()) {
System.out.println(st2.nextElement());
}
}
这是我用于拆分大型 (1GB+) 制表符分隔文件的方法。它被限制为 char
定界符以避免任何额外方法调用的开销(这可能会被运行时优化),但它可以很容易地转换为字符串定界符。如果有人能想出更快的方法或对此方法进行改进,我会很感兴趣。
public static String[] split(final String line, final char delimiter)
{
CharSequence[] temp = new CharSequence[(line.length() / 2) + 1];
int wordCount = 0;
int i = 0;
int j = line.indexOf(delimiter, 0); // first substring
while (j >= 0)
{
temp[wordCount++] = line.substring(i, j);
i = j + 1;
j = line.indexOf(delimiter, i); // rest of substrings
}
temp[wordCount++] = line.substring(i); // last substring
String[] result = new String[wordCount];
System.arraycopy(temp, 0, result, 0, wordCount);
return result;
}
为了这个问题,假设我有一个 String
,其中包含值 Two;.Three;.Four
(依此类推),但元素由 ;.
分隔。
现在我知道有多种拆分字符串的方法,例如 split()
和 StringTokenizer
(速度更快且效果很好)但我的输入文件约为 1GB 并且我正在寻找比 StringTokenizer
.
经过一些研究,我发现 indexOf
和 substring
非常有效,但示例只有单个分隔符或结果仅返回单个 word/element.
示例代码使用 indexOf
和 substring
:
String s = "quick,brown,fox,jumps,over,the,lazy,dog";
int from = s.indexOf(',');
int to = s.indexOf(',', from+1);
String brown = s.substring(from+1, to);
以上内容适用于打印 brown
,但我如何使用 indexOf
和 substring
拆分具有多个分隔符的行并显示所有项目,如下所示。
预期输出
Two
Three
Four
....and so on
如果你想要极致的效率,我根本不会使用Strings
,更不用说拆分它们了。我会做编译器做的事情:一次处理一个字符的文件。使用具有较大缓冲区大小的 BufferedReader
,例如 128kb,并一次读取 char
,将它们累积成 StringBuilder
,直到获得 ;
或行终止符.
StringTokenizer
比 StringBuilder
.
public static void main(String[] args) {
String str = "This is String , split by StringTokenizer, created by me";
StringTokenizer st = new StringTokenizer(str);
System.out.println("---- Split by space ------");
while (st.hasMoreElements()) {
System.out.println(st.nextElement());
}
System.out.println("---- Split by comma ',' ------");
StringTokenizer st2 = new StringTokenizer(str, ",");
while (st2.hasMoreElements()) {
System.out.println(st2.nextElement());
}
}
这是我用于拆分大型 (1GB+) 制表符分隔文件的方法。它被限制为 char
定界符以避免任何额外方法调用的开销(这可能会被运行时优化),但它可以很容易地转换为字符串定界符。如果有人能想出更快的方法或对此方法进行改进,我会很感兴趣。
public static String[] split(final String line, final char delimiter)
{
CharSequence[] temp = new CharSequence[(line.length() / 2) + 1];
int wordCount = 0;
int i = 0;
int j = line.indexOf(delimiter, 0); // first substring
while (j >= 0)
{
temp[wordCount++] = line.substring(i, j);
i = j + 1;
j = line.indexOf(delimiter, i); // rest of substrings
}
temp[wordCount++] = line.substring(i); // last substring
String[] result = new String[wordCount];
System.arraycopy(temp, 0, result, 0, wordCount);
return result;
}