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

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()怎样返回字符串对象?

再看另外一个问题:

  public static void main(String[] args) {
     String str1 = "abc  ";
     String str2 = "abc";
     String str3 = "abc";
     str1 = str1.trim();
     System.out.println(str1 == str2); // false
     System.out.println(str3 == str2); // true
  }

str1.trim()返回的字符串为”abc”,而在常量池中已经确定存在这个”abc”这个String对象,那为何str1==str2不成立呢?
我们看trim()方法的最后一行:

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

也就是说,trim()方法实际上的行为并不是”去掉两端的空白字符“,而是”截取中间的非空白字符“。

再看substring()方法:

  public String substring(int beginIndex, int endIndex) {
    if (beginIndex < 0) {
      throw new StringIndexOutOfBoundsException(beginIndex);
    }
    if (endIndex > value.length) {
      throw new StringIndexOutOfBoundsException(endIndex);
    }
    int subLen = endIndex - beginIndex;
    if (subLen < 0) {
      throw new StringIndexOutOfBoundsException(subLen);
    }
    return ((beginIndex == 0) && (endIndex == value.length)) ? this
        : new String(value, beginIndex, subLen);
  }

我们看到,当实际发生了”截取“这个动作的时候,因为此处无法直接声明一个String常量,即substring()无法像我们写String str = “abc”这样直接在常量池中创建对象,所以它返回的是一个new出来的对象,这个对象位于Heap内存中。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • java中string.trim()函数的作用实例及源码

    trim()的作用:去掉字符串首尾的空格. public static void main(String arg[]){ String a=" hello world "; String b="hello world"; System.out.println(b.equals(a)); a=a.trim(); //去掉字符串首尾的空格 System.out.println(a.equals(b)); } 执行结果: a: hello world ,false a:h

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

    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**

  • java string类的常用方法详细介绍

    String : 字符串类型 一.构造函数 复制代码 代码如下: String(byte[ ] bytes):通过byte数组构造字符串对象. String(char[ ] value):通过char数组构造字符串对象. String(Sting original):构造一个original的副本.即:拷贝一个original. String(StringBuffer buffer):通过StringBuffer数组构造字符串对象. 例如: 复制代码 代码如下: byte[] b = {'a',

  • java String源码和String常量池的全面解析

    1. String 介绍,常用方法源码分析 2. String 常量池分析 常用方法 equals trim replace concat split startsWith 和 endsWith substring toUpperCase() 和 toLowerCase() compareTo String 介绍 String类被final所修饰,也就是说String对象是不可变量,并发程序最喜欢不可变量了.String类实现了Serializable, Comparable, CharSequ

  • Java String类的常用方法汇总

    一.String类 String类在java.lang包中,java使用String类创建一个字符串变量,字符串变量属于对象.java把String类声明的final类,不能有类.String类对象创建后不能修改,由0或多个字符组成,包含在一对双引号之间. 二.String类对象的创建 字符串声明:String stringName; 字符串创建:stringName = new String(字符串常量);或stringName = 字符串常量; 三.String类构造方法 1.public

  • java String的深入理解

    java String的深入理解 一.Java内存模型  按照官方的说法:Java 虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配. JVM主要管理两种类型内存:堆和非堆,堆内存(Heap Memory)是在 Java 虚拟机启动时创建,非堆内存(Non-heap Memory)是在JVM堆之外的内存. 简单来说,非堆包含方法区.JVM内部处理或优化所需的内存(如 JITCompiler,Just-in-time Compiler,即时编译后的代码缓存).每个类结构(如

  • java String类功能、原理与应用案例【统计、判断、转换等】

    本文实例讲述了java String类功能.原理与应用.分享给大家供大家参考,具体如下: String构造方法 package cn.itcast_01; /* * 字符串:就是由多个字符组成的一串数据.也可以看成是一个字符数组. * 通过查看API,我们可以知道 * A:字符串字面值"abc"也可以看成是一个字符串对象. * B:字符串是常量,一旦被赋值,就不能被改变. * * 构造方法: * public String():空构造 * public String(byte[] by

  • Java String中移除空白字符的多种方式汇总

    前言 字符串,是Java中最常用的一个数据类型了.我们在日常开发时候会经常使用字符串做很多的操作.比如字符串的拼接.截断.替换等. 这一篇文章,我们介绍一个比较常见又容易被忽略的一个操作,那就是移除字符串中的空格. 其实,在Java中从字符串中删除空格有很多不同的方法,如trim,replaceAll等.但是,在Java 11添加了一些新的功能,如strip.stripLeading.stripTrailing等. 大多数时候,我们只是使用trim方法来删除多余的空格.但是好像很多人并没有去思考

  • 详解Java String类常用方法有哪些

    一.构造器 实质是给底层的char数组value赋值 String s1 = new String(); String s2 = new String("abc"); String s3 = new String(new char[]{'a','b','c'}); 二.方法 str.length() 字符串长度本质是底层的char数组的长度 str.isEmpty() 本质是判断底层char数组长度是否为0 str.charAt(i) 本质是取底层char数组的第i个元素(字符) st

  • 5分钟快速了解String.trim()到底做了什么事

    目录 前言 说我们认知的trim() 复习一个小概念 养成一个好习惯 动起来,不瞎掰 示例1 示例2 示例3 示例4 示例5 示例6 5分钟直接看这里 总结 前言 项目中遇到用String.trim()的地方,点进去看了trim()源码,以前一直以为trim()的作用只是去除字符串中的首尾的"空格"符,但是源码看下来,好像这个说法不太准确呢. 搞技术嘛,严谨一些,在这记录一下,大佬们也瞅瞅哈~ 说我们认知的trim() 说到String.trim() 函数 ,就像前言说的一样,我的认知

随机推荐