当前位置 主页 > 网站技术 > 代码类 > 最大化 缩小

    Java string.trim()究竟去掉了什么

    栏目:代码类 时间:2019-12-02 12:11

    String.Trim()方法到底为我们做了什么,仅仅是去除字符串两端的空格吗?

    trim()方法去掉了哪些字符? trim()/substring()怎样返回字符串对象?

    trim()方法去掉了哪些字符?

    在Stack Overflow上看到一个问题(点此查看):

    I am receiving a string from server trailing one or two lines of spaces like below given string.

    String str = "abc*******     
         ********";
    

    Consider * as spaces after my string

    i have tried a few methods like

    str = str.trim();
    
    str = str.replace(String.valueOf((char) 160), " ").trim();
    
    str = str.replaceAll("\u00A0", "");
    
    

    but none is working. Why i am not able to remove the space?

    为此看了一下trim()方法的源码,发现挺有意思的。

    先看下面的代码:

      public static void main(String[] args) {
         String str = "abc";
         System.out.println(str.length());
         str = str.trim();
         System.out.println(str.length());
      }
    

    我不清楚各位在刚学习Java的时候老师(或者书上)是怎么说的,我入门是看毕向东老师的视频,当时毕向东老师说的是trim()方法会去掉字符串两端的空格;后来看《Java核心技术》的时候,书上说的时“返回一个新的字符串。这个字符串将删除了原始字符串头部和尾部的空格。”(第9版的中文版,在卷一51页20行。)所以我一直理所当然地认为trim()方法会trim掉字符串两端的“空格”,也正是如此,我看到源码的时候才会觉得很有意思。

    不说别的,上面代码输出的是9、3,也就是字符串尾部的””被trim()掉了。

    更有意思的是,如果你把上面的代码copy到Notepad++上,它长成这样:

    而在Eclipse上,它长这样:

    没错,这个特殊的符号在Eclipse上是看不到、不占任何“空间”的,如果我们不小心在代码中混入这样的字符,估计排错会很痛苦……

    再接入正题,现在我们知道了trim()方法不只trim掉空格那么简单,那么它究竟trim掉了些什么东西?我们不妨来看一下。

      /**
       * @return A string whose value is this string, with any leading and trailing white
       *     space removed, or this string if it has no leading or
       *     trailing white space.
       */
      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;
      }

    原文的”white space“中文直译为”留白“或”空白“,但是常见文档一般翻译为”空格“,而空格的英文一般应译为”blank”或”space”,所以我认为这里的翻译不够准确(当然源码注解也没有写得很清楚),而且会引起歧义:trim()方法实际上trim掉了字符串两端Unicode编码小于等于32(\u0020)的所有字符。

    System.out.println("' '的Unicode编码为:" + (int)' '); // ' '的Unicode编码为:32

    trim()/substring()怎样返回字符串对象?