" world "
。该字符串只有前后空格。在这种情况下,trim()
比 replace()
更快吗?我曾经使用过
replace()
,但我的导师说不要使用它,因为trim()
可能更快。如果不是,
trim()
和replace()
有什么优势?" world "
。该字符串只有前后空格。在这种情况下,trim()
比 replace()
更快吗?replace()
,但我的导师说不要使用它,因为trim()
可能更快。trim()
和replace()
有什么优势?replace()
方法: public String replace(CharSequence target, CharSequence replacement) {
String tgtStr = target.toString();
String replStr = replacement.toString();
int j = indexOf(tgtStr);
if (j < 0) {
return this;
}
int tgtLen = tgtStr.length();
int tgtLen1 = Math.max(tgtLen, 1);
int thisLen = length();
int newLenHint = thisLen - tgtLen + replStr.length();
if (newLenHint < 0) {
throw new OutOfMemoryError();
}
StringBuilder sb = new StringBuilder(newLenHint);
int i = 0;
do {
sb.append(this, i, j).append(replStr);
i = j + tgtLen;
} while (j < thisLen && (j = indexOf(tgtStr, j + tgtLen1)) > 0);
return sb.append(this, i, thisLen).toString()
}
与trim()
相比:
public String trim() {
int len = value.length;
int st = 0;
char[] val = value; /* avoid getfield opcode */
while ((st < len) && (val[st] <= ' ')) {
st++;
}
while ((st < len) && (val[len - 1] <= ' ')) {
len--;
}
return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
}
正如您所看到的,replace()
调用多个其他方法并在整个 String
中进行迭代,而 trim()
仅在 String
的开头和结尾进行迭代,直到字符不是空格。因此,在仅尝试删除单词前后的空格时,trim()
更有效率。
我们可以对此运行一些基准测试:
public static void main(String[] args) {
long testStartTime = System.nanoTime();;
trimTest();
long trimTestTime = System.nanoTime() - testStartTime;
testStartTime = System.nanoTime();
replaceTest();
long replaceTime = System.nanoTime() - testStartTime;
System.out.println("Time for trim(): " + trimTestTime);
System.out.println("Time for replace(): " + replaceTime);
}
public static void trimTest() {
for(int i = 0; i < 1000000; i ++) {
new String(" string ").trim();
}
}
public static void replaceTest() {
for(int i = 0; i < 1000000; i ++) {
new String(" string ").replace(" ", "");
}
}
输出:
Time for trim(): 53303903
Time for replace(): 485536597
//432,232,694 difference
replace
中的调用次数确实比我预期的要多得多。不过,这取决于具体实现。我认为规则是在适用trim
的情况下使用它,在需要时使用replace
。只有当运行真实代码的分析器说某个部分需要优化时才进行优化。 - markspacetrim()
)将与执行相同操作的通用方法(如replace(...)
)一样快,甚至更快。如果特定用途的方法较慢,则其实现可以重新编写为等效调用通用方法,从而在大多数情况下性能相当。称职的程序员会这样做,因为它可以降低维护成本。
在特定用途的方法中,可能存在无法应用于通用情况的优化。
trim()
只需要查看字符串的开头和结尾...而replace(...)
需要查看字符串中的所有字符。(我们可以从各自方法的描述中推断出这一点。)trim()
实现为检查所有字符的子优化2。
trim()
与replace(...)
的情况下显然适用。
trim()
是一种更快捷的输入方式,它不需要任何参数。
同时理解你的意图也更加迅速明了。你想对字符串进行修剪,而不是替换其中所有包含空格的部分为空字符串,并且在其他情境中知道该字符串仅在开头和结尾有空格。
从任何角度看,使用trim()
都比较快速。不要让阅读你代码的人生活变得复杂。大多数情况下,这个人将会是你几个月后,或至少是你不讨厌的某个人。
Trim将修剪外部字符,直到它们不是空格。我认为它们修剪空格、制表符和换行符。
Replace将扫描整个字符串(因此,它可以是一个句子),并用“”替换内部的“”,从而将它们压缩在一起。
它们有不同的用例,显然,一个是清理用户输入,而另一个是在找到匹配项后使用其他内容更新字符串。
话虽如此,运行时间:替换将在N时间内运行,因为它将查找所有匹配的字符。Trim将在O(N)中运行,但很可能只是每端少量字符。
我认为,修剪背后的想法是人们会在键入和输入事物时意外地在提交表单之前按下空格,从而尝试保存字段“Foo ”而不是“Foo”。
s.trim()
缩短了一个 String s
。这意味着不需要将字符从一个索引移动到另一个索引。它从 String
的第一个字符 (s.toCharArray()[0]
) 开始,逐个字符缩短 String
,直到出现第一个非空格字符。它以相同的方式缩短字符串末尾的 String
。因此,它压缩了 String
。如果一个 String
没有前导和尾随空格,则在检查第一个和最后一个字符后,trim
将准备就绪。
对于 " world ".trim()
,需要两个步骤:一个是删除第一个索引上的前导空格,第二个是删除最后一个索引上的尾随空格。
" world ".replace(" ", "")
至少需要 n = " world ".length()
步。它必须检查每个字符是否需要替换。但是,如果我们考虑到 String.replace(...)
的实现需要编译一个 Pattern
,构建一个 Matcher
,然后替换所有匹配的区域,与缩短一个 String
相比,它似乎更加复杂。
我们还必须考虑到 " world ".replace(" ", "")
不会替换空格,而只会替换字符串 " "
。由于 String replace(CharSequence target, CharSequence replacement)
使用 Pattern.LITERAL
编译目标,因此我们无法使用字符类 \s。为了更准确,我们应该将 " world ".trim()
与 " world ".replaceAll("\\s", "")
进行比较。这仍然不同,因为在 String trim()
中,空格被定义为对于 s.toCharArray()
中的每个 c
,c <= ' '
。
总结:对于长字符串来说,String.trim()
应该更快。
关于方法如何工作的描述是基于Java 8中String
的实现。但是实现可能会改变。
但问题应该是:您打算如何处理字符串?您想要修剪它还是替换一些字符?根据使用相应的方法进行操作。
trim
仅在开头和结尾起作用,而replace
会替换字符串中间的字符。 - markspace