java string.trim方法实现细节

时间:2018-09-06 09:44:19

标签: java

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;
}
  1. 为什么使用val[st] <= ' ',而不是val[st] == ''
  2. (st > 0) || (len < value.length)是什么意思。

3 个答案:

答案 0 :(得分:3)

  1. val[st] == ''在语法上不正确。 ''不是char文字。
  2. st > 0表示起始位置不是0len < value.length的长度小于字符串的长度。这是优化,如果没有要修剪的内容,它将返回this

编辑

如果您的第一个问题是为什么不检查val[st] == ' ',答案是:这是因为trim不仅删除了空格,而且还删除了新行和新制表符。实际上,它删除了很多不可打印的字符,例如'\ b'(在打印时发出声音的字符)。所有这些字符的ASCII代码少于32(空白代码)。

答案 1 :(得分:2)

trim()在字符串的开头或结尾去除空格和控制字符。

执行<= ' '后,您将检查空格或任何控制字符。

return ((st > 0) || (len < value.length)) ? substring(st, len) : this;

您可以在这一行中看到,如果它会使String变小,它只会占用一个子字符串,否则它将返回原始String。

您可能会认为此检查是多余的,因为substring执行相同的检查

    return ((beginIndex == 0) && (endIndex == value.length)) ? this
            : new String(value, beginIndex, subLen);

但是,如果未修剪字符串,这可以避免边界检查。甚至更好的是即使使用子字符串也要避免边界检查。

答案 2 :(得分:1)

1)MenuItem.js甚至不是一个可能的字符。假设这是一个错字,您的意思是要问为什么使用''而不是<= ' '

== ' '(一个空格)的unicode值为32。由于' '不仅删除空格,还删除了制表符和换行符(分别具有unicode值.trim9 ),之所以使用10是因为它比(val[st] <= ' ')短(除制表符和换行符之外,其他(val[st] == '\t' || val[st] == '\n' || val[st] == ' ')范围内的unicode值都是不可打印的/控制字符,因此它们也会被修剪)显然)。


2)[0, 32)表示,如果找到任何尾随和/或前导空格,则通过返回范围return ((st > 0) || (len < value.length)) ? substring(st, len) : this;中的子字符串将其删除。如果没有前导或尾随空格,则返回[str, len)(字符串输入本身)。

注意/有趣的事实:这也意味着您可以执行类似this而不是boolean containsTrailingAndOrLeadingWhitespaces = strInput.trim() != strInput;的操作,因为返回的是!strInput.trim().equals(strInput)本身(以及相同的引用),而不是新的字符串(不过不推荐)。

相关问题