Java笔记之java.lang.String#trim
String的trim()方法是使用频率频率很高的一个方法,直到不久前我不确定trim去除两端的空白符时对换行符是怎么处理的点进去看了下源码的实现,才发现String#trim的实现跟我想像的完全不一样,原来一直以来我对这个函数存在着很深的误解。
我想的trim方法是类似于下面这样的:
package cc11001100.trimStudy; /**
* @author CC11001100
*/
public class CustomString { private char[] values; public CustomString(char[] values) {
this.values = values;
} // ... public CustomString trim() {
char[] localValues = values;
int left = 0, right = localValues.length;
while (left < right && isBlankChar(localValues[left])) {
left++;
}
while (right > left && isBlankChar(localValues[right - 1])) {
right--;
}
if (left != 0 || right != localValues.length) {
char[] newValue = new char[right - left];
System.arraycopy(localValues, left, newValue, 0, newValue.length);
return new CustomString(newValue);
} else {
return this;
}
} private boolean isBlankChar(char c) {
return c == ' ' || c == '\t' || c == '\r' || c == '\n';
} @Override
public String toString() {
return new java.lang.String(values);
} // ... }
即去除字符串两边的回车换行、制表符、回车换行符等等,然而String#trim的实际实现是这样的:
/**
* Returns a string whose value is this string, with any leading and trailing
* whitespace removed.
* <p>
* If this {@code String} object represents an empty character
* sequence, or the first and last characters of character sequence
* represented by this {@code String} object both have codes
* greater than {@code '\u005Cu0020'} (the space character), then a
* reference to this {@code String} object is returned.
* <p>
* Otherwise, if there is no character with a code greater than
* {@code '\u005Cu0020'} in the string, then a
* {@code String} object representing an empty string is
* returned.
* <p>
* Otherwise, let <i>k</i> be the index of the first character in the
* string whose code is greater than {@code '\u005Cu0020'}, and let
* <i>m</i> be the index of the last character in the string whose code
* is greater than {@code '\u005Cu0020'}. A {@code String}
* object is returned, representing the substring of this string that
* begins with the character at index <i>k</i> and ends with the
* character at index <i>m</i>-that is, the result of
* {@code this.substring(k, m + 1)}.
* <p>
* This method may be used to trim whitespace (as defined above) from
* the beginning and end of a string.
*
* @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;
}
会将字符串两侧小于空格的字符都去除掉,这里可以简单的将\u005Cu0020理解为ASCII 0x20,即十进制的32,在ASCII码表中小于等于32的字符都将被去除:

先来看一下trim必须要去除的几个字符:
\t是9
\r是13
\n是10
这几个字符倒是都小于空格,而且前31位都是不可见字符,32是空格,这样做的话好像也没有太大的毛病,只是以后再使用trim的时候要想一下自己的数据有没有可能出现小于32不是空格制表符换行之类又需要保留的。
下面是对String#trim的一个简单测试:
package cc11001100.trimStudy; /**
* @author CC11001100
*/
public class TrimStudy { public static void main(String[] args) { StringBuilder sb = new StringBuilder();
for (int i = 0; i < 128; i++) {
sb.append((char) i);
}
String s = sb.toString().trim();
// trim效果
System.out.println("-" + s + "-");
// trim之后第一个字符的ASCII码
System.out.println((int) s.charAt(0));
// 删除
System.out.println((char) 127);
// 查看其它空白字符的打印效果
System.out.println(sb.toString()); } }
运行结果:
注意ASCII 127删除字符应该也可以算作是不可见的空白字符。
后来我不死心,又去找了被依赖超多次数的Apache commons-lang中StringUtils#trim的实现:
/**
* <p>Removes control characters (char <= 32) from both
* ends of this String, handling <code>null</code> by returning
* <code>null</code>.</p>
*
* <p>The String is trimmed using {@link String#trim()}.
* Trim removes start and end characters <= 32.
* To strip whitespace use {@link #strip(String)}.</p>
*
* <p>To trim your choice of characters, use the
* {@link #strip(String, String)} methods.</p>
*
* <pre>
* StringUtils.trim(null) = null
* StringUtils.trim("") = ""
* StringUtils.trim(" ") = ""
* StringUtils.trim("abc") = "abc"
* StringUtils.trim(" abc ") = "abc"
* </pre>
*
* @param str the String to be trimmed, may be null
* @return the trimmed string, <code>null</code> if null String input
*/
public static String trim(String str) {
return str == null ? null : str.trim();
}
然而也只是调用了String#trim,也不是我想象的那样….
看来我一直以来都对trim有着很深的误解,trim是编程中对字符串处理的一个比较通用的概念,也不知道其它语言的具体实现是怎样的。
.
Java笔记之java.lang.String#trim的更多相关文章
- java.lang.String.trim(), 不仅仅去掉空格
由于我们处理的日志需要过滤一些空格,因此大部分处理日志的程序中都用到了java.lang.String.trim()函数.直到有一次遇到一个诡异的问题,某个包含特殊字符的字符串被trim后居然也为 ...
- 转 Java笔记:Java内存模型
Java笔记:Java内存模型 2014.04.09 | Comments 1. 基本概念 <深入理解Java内存模型>详细讲解了java的内存模型,这里对其中的一些基本概念做个简单的笔记 ...
- 菜鸡的Java笔记 第十四 String 类常用方法
/*String 类常用方法 将所有String类的常用方法全部记下来,包括方法名称,参数作用以及类型 一个成熟的编程语言,除了它的语法非常完善之外,那么也需要提供有大量的开发类库 ...
- java 笔记(4) —— java I/O 流、字节流、字符流
Java中使用流来处理程序的输入和输出操作,流是一个抽象的概念,封装了程序数据于输入输出设备交换的底层细节.JavaIO中又将流分为字节流和字符流,字节流主要用于处理诸如图像,音频视频等二进制格式数据 ...
- 疯狂java笔记(七) - Java集合之Map
Map是以键值对(key-value)的形式来存储数据的.而且Map不允许key的重复,通过Map存储key-value对时,只需要考虑key的存储就可以,key存储后value就会跟着key(完全可 ...
- Java笔记:Java集合概述和Set集合
本文主要是Java集合的概述和Set集合 1.Java集合概述 1)数组可以保存多个对象,但数组长度不可变,一旦在初始化数组时指定了数组长度,这个数组长度就是不可变的,如果需要保存数量变化的数据,数组 ...
- Java笔记:Java 流(Stream)、文件(File)和IO
更新时间:2018-1-7 12:27:21 更多请查看在线文集:http://android.52fhy.com/java/index.html java.io 包几乎包含了所有操作输入.输出需要的 ...
- 菜鸡的Java笔记 简单JAVA 类的开发原则以及具体实现
/* 现在要求定义一个雇员信息类 在这个类之中包含有雇员编号 姓名 职位 基本工资 佣金等信息 对于此时给定要求实际上就是描述一类事物,而这样的程序类在在java之中可以将其称为简单java类 ...
- java笔记--理解java类加载器以及ClassLoader类
类加载器概述: java类的加载是由虚拟机来完成的,虚拟机把描述类的Class文件加载到内存,并对数据进行校验,解析和初始化,最终形成能被java虚拟机直接使用的java类型,这就是虚拟机的类加载机制 ...
随机推荐
- 一份超全超详细的 ADB 用法大全
http://blog.csdn.net/u010375364/article/details/52344120
- TeamWork#3,Week5,Release Notes of the Alpha Version
在这里的是一款你时下最不可或缺的一款美妙的产品. “今天哪家外卖便宜?” “今天这家店在哪个网站打折?” “这家店到底哪个菜好吃?” 这些问题你在寝室/办公室每天要问几次?还在为了找一家便宜的外卖店而 ...
- 【SE】Week7 : Silver Bullet & Cathedral and Bazaar & Big Ball of Mud & Waterfall ...
1. Silver Bullet No Silver Bullet: Essence and Accidents of Software Engineering —— 无银弹理论,出自于美国1999年 ...
- 20135316Linux内核学习笔记第五周
20135316王剑桥<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 一.给MenuOS增加time和t ...
- APP相关问题汇总
APP试用过程中,我们的APP存在不少的问题,下面是一些试用者和我们自己发现的一些问题以及一些建议. 1.APP界面有些老气,界面之间过渡僵硬 2.在试用中会出现闪退情况 3.由于我们使用的是绝对布局 ...
- 第二个spring冲刺第5天
针对与昨天的讨论内容,今天进行了开会研讨给意见. 在今天中有了点进展,各方面都有改善,离程序的完成度又前进了一大步.
- 四则运算app第一阶段冲刺
第一阶段冲刺 [开发环境]:eclipse [开发项目]:小学生四则运算APP [开发人员]:郑胜斌 http://www.cnblogs.com/zsb1/ 孔德颖 http://www.cnblo ...
- A+B Format 思路及解题过程结果
A+B Format 思路及解题过程结果 github链接 题目 解题思路 这个题目的难点在于每三位用逗号隔开,以及带不带负号的问题.第一个问题,我的解决办法是先通过取整来取数,再通过取余来去数.第二 ...
- PHP 验证IP的合法性
php验证IP的合法性! function get_ip(){ //判断服务器是否允许$_SERVER if(isset($_SERVER)){ if(isset($_SERVER[HTTP_X_FO ...
- Lua 调试库
Lua 调试库 http://blog.csdn.net/vermilliontear/article/details/50851045 http://blog.csdn.net/vermillion ...