java.lang.String的trim()方法详解

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

一直以为Trim()方法就是把字符串两端的空格字符给删去,其实我错了,而且错的比较离谱。

首先我直接反编译String类,找到Trim()方法:

public string Trim()
{    return this.TrimHelper(WhitespaceChars, 2);
}

TrimHelper方法有两个参数,第一个参数名WhitespaceChars,首字母尽然是大写的,肯定有文章,真不出我所料:

internal static readonly char[] WhitespaceChars;

这里只是定义它,没有赋值,而且是静态的,我们看看构造函数去,果然找到:

static String()

{ Empty = " "; WhitespaceChars = new char[] { ‘/t‘, ‘/n‘, ‘/v‘, ‘/f‘, ‘/r‘, ‘ ‘, ‘/x0085‘, ‘/x00a0‘, ‘?‘, ‘?‘, ‘?‘, ‘?‘, ‘?‘, ‘?‘, ‘?‘, ‘?‘, ‘?‘, ‘?‘, ‘?‘, ‘?‘, ‘?‘, ‘/u2028‘, ‘/u2029‘, ‘ ‘, ‘?‘ }; }

Trim方法就是把字符串两端的这些字符给删去?我很坚定的猜想到。

继续我们的探索,直接反编译TrimHelper,哇,也许这个才是我想要的,私有的TrimHelper方法:

private string TrimHelper(char[] trimChars, int trimType)
{    int num = this.Length - 1;    int startIndex = 0;    if (trimType != 1)
    {
        startIndex = 0;        while (startIndex < this.Length)
        {            int index = 0;            char ch = this[startIndex];
            index = 0;            while (index < trimChars.Length)
            {                if (trimChars[index] == ch)
                {                    break;
                }
                index++;
            }            if (index == trimChars.Length)
            {                break;
            }
            startIndex++;
        }
    }    if (trimType != 0)
    {
        num = this.Length - 1;        while (num >= startIndex)
        {            int num4 = 0;            char ch2 = this[num];
            num4 = 0;            while (num4 < trimChars.Length)
            {                if (trimChars[num4] == ch2)
                {                    break;
                }
                num4++;
            }            if (num4 == trimChars.Length)
            {                break;
            }
            num--;
        }
    }    int length = (num - startIndex) + 1;    if (length == this.Length)
    {        return this;
    }    if (length == 0)
    {        return Empty;
    }    return this.InternalSubString(startIndex, length, false);
}

经过分析和运行,基本上知道了这个方法是干什么的了。

TrimHelper方法有两个参数:

第一个参数trimChars,是要从字符串两端删除掉的字符的数组;

第二个参数trimType,是标识Trim的类型。就目前发现,trimType的取值有3个。当传入0时,去除字符串头部的空白字符,传入1时去除字符串尾部的空白字符,传入其他数值(比如2) 去除字符串两端的空白字符。

最后再看看真正执行字符串截取的方法:

private unsafe string InternalSubString(int startIndex, int length, bool fAlwaysCopy)
{    if (((startIndex == 0) && (length == this.Length)) && !fAlwaysCopy)
    {        return this;
    }    string str = FastAllocateString(length);    fixed (char* chRef = &str.m_firstChar)
    {        fixed (char* chRef2 = &this.m_firstChar)
        {
            wstrcpy(chRef, chRef2 + startIndex, length);
        }
    }    return str;
}

原来也用指针的?第一次看到,效率应该比较高吧。 
最后总结一下: 
String.Trim()方法会去除字符串两端,不仅仅是空格字符,它总共能去除25种字符: 
(‘/t‘, ‘/n‘, ‘/v‘, ‘/f‘, ‘/r‘, ‘ ‘, ‘/x0085‘, ‘/x00a0‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘?‘, ‘/u2028‘, ‘/u2029‘, ‘ ‘, ‘?‘)

如果你想保留其中的一个或多个(例如/t制表符,/n换行符,/r回车符等),请慎用Trim方法。

请注意,Trim删除的过程为从外到内,直到碰到一个非空白的字符为止,所以不管前后有多少个连续的空白字符都会被删除掉。

最后附上两个相关的方法(也是String类直接提供的),分别去除字符串头部空白字符的TrimStart方法和去除字符串尾部空白字符的 TrimEnd方法:

TrimStart和TrimEnd方法

如果想去除字符串两端其他任意字符,可以考虑Trim他的重载兄弟:String.Trim(Char[]),传入你想要去除的哪些字符的数组。

源码奉上:

public string Trim(params char[] trimChars)
{    if ((trimChars == null) || (trimChars.Length == 0))
    {
        trimChars = WhitespaceChars;
    }    return this.TrimHelper(trimChars, 2);
}

空格 != 空白字符,删除空格请使用: Trim(‘ ‘);

时间: 2024-11-08 18:27:34

java.lang.String的trim()方法详解的相关文章

Java AtomicInteger类的使用方法详解_java - JAVA

文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 首先看两段代码,一段是Integer的,一段是AtomicInteger的,为以下: public class Sample1 { private static Integer count = 0; synchronized public static void increment() { count++; } } 以下是AtomicInteger的: public class Sample2 { private s

String的Intern方法详解

引言 在 JAVA 语言中有8中基本类型和一种比较特殊的类型String.这些类型为了使他们在运行过程中速度更快,更节省内存,都提供了一种常量池的概念.常量池就类似一个JAVA系统级别提供的缓存.8种基本类型的常量池都是系统协调的,String类型的常量池比较特殊.它的主要使用方法有两种: 直接使用双引号声明出来的String对象会直接存储在常量池中. 如果不是用双引号声明的String对象,可以使用String提供的intern方法.intern 方法会从字符串常量池中查询当前字符串是否存在,

Java中的==和equals方法详解

Java中的==和equals   1.如果比较对象是值变量:只用== 2.如果比较对象是引用型变量: ==:比较两个引用是不是指向同一个对象实例. equals: 首先Object类中equals的实现是直接调用了==操作. 一个自定义类继承自Object且没有重写equals方法,那么其equals操作也是与Object类一样,仅仅是直接调用==操作. 如果一个类重写过equals方法(或者继承自一个重写过equals方法的类),那么效果与==操作不同 如果是你自己定义的一个类,比较自定义类

基于Java内存溢出的解决方法详解

一.内存溢出类型 1.java.lang.OutOfMemoryError: PermGen space JVM管理两种类型的内存,堆和非堆.堆是给开发人员用的上面说的就是,是在JVM启动时创建:非堆是留给JVM自己用的,用来存放类的信息的.它和堆不同,运行期内GC不会释放空间.如果web app用了大量的第三方jar或者应用有太多的class文件而恰好MaxPermSize设置较小,超出了也会导致这块内存的占用过多造成溢出,或者tomcat热部署时侯不会清理前面加载的环境,只会将context

Java中 hashCode()方法详解

先来看下Object源码里hashcode方法: /**     * Returns a hash code value for the object. This method is      * supported for the benefit of hashtables such as those provided by      * <code>java.util.Hashtable</code>.      * <p>     * The general co

java中String的.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] <= ' ')) { le

[转载]Java中hashCode与equal方法详解

转载自http://blog.csdn.net/jiangwei0910410003/article/details/22739953 Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要重写这两个方法,今天就来介绍一些这两个方法的作用. equals()和hashCode()方法是用来在同一类中做比较用的,尤其是在容器里如set存放同一类对象时用来判断放入的对象是否重复. 这里我们首先要明白一个问题: equa

String类equals()方法详解

下面我们先看一段代码: 这段代码输出的结果为: ture true -------------- false 咋看之下貌似Object类比较特别,那么我们看一下Object下的equals()方法的源代码 Object下的queals()方法十分简单,就是单纯的判断这两个引用是不是指向同一个对象,是的话返回true,不是的话返回false. 可是把这个方法应用在上面代码的String对象身上明显不对,那么String类里面必定重写了equals()方法,来看一下它的源代码: 重这个方法的源代码可

java.lang.String的一些方法

char charAt(int index) 返回指定索引处的char值 int codePoinAt(int index) 返回指定索引之前的字符(Unicode) int compareTo(Sting anotherString) 按字典顺序比较两个字符串 int hashCode() 返回此字符串的哈希代码 in indexOf(int ch) 返回指定字符在此字符串中第一次出现处的索引 boolean matches(String regex) 通知此字符串是否匹配给定的正则表达式 S