Java string.trim()究竟去掉了什么
String.Trim()方法到底為我們做了什么,僅僅是去除字符串兩端的空格嗎?
- trim()方法去掉了哪些字符?
- trim()/substring()怎樣返回字符串對(duì)象?
trim()方法去掉了哪些字符?
在Stack Overflow上看到一個(gè)問題(點(diǎn)此查看):
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()方法的源碼,發(fā)現(xiàn)挺有意思的。
先看下面的代碼:
public static void main(String[] args) { String str = "abc"; System.out.println(str.length()); str = str.trim(); System.out.println(str.length()); }
我不清楚各位在剛學(xué)習(xí)Java的時(shí)候老師(或者書上)是怎么說的,我入門是看畢向東老師的視頻,當(dāng)時(shí)畢向東老師說的是trim()方法會(huì)去掉字符串兩端的空格;后來(lái)看《Java核心技術(shù)》的時(shí)候,書上說的時(shí)“返回一個(gè)新的字符串。這個(gè)字符串將刪除了原始字符串頭部和尾部的空格?!保ǖ?版的中文版,在卷一51頁(yè)20行。)所以我一直理所當(dāng)然地認(rèn)為trim()方法會(huì)trim掉字符串兩端的“空格”,也正是如此,我看到源碼的時(shí)候才會(huì)覺得很有意思。
不說別的,上面代碼輸出的是9、3,也就是字符串尾部的””被trim()掉了。
更有意思的是,如果你把上面的代碼copy到Notepad++上,它長(zhǎng)成這樣:
而在Eclipse上,它長(zhǎng)這樣:
沒錯(cuò),這個(gè)特殊的符號(hào)在Eclipse上是看不到、不占任何“空間”的,如果我們不小心在代碼中混入這樣的字符,估計(jì)排錯(cuò)會(huì)很痛苦……
再接入正題,現(xiàn)在我們知道了trim()方法不只trim掉空格那么簡(jiǎn)單,那么它究竟trim掉了些什么東西?我們不妨來(lái)看一下。
/** * @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“中文直譯為”留白“或”空白“,但是常見文檔一般翻譯為”空格“,而空格的英文一般應(yīng)譯為”blank”或”space”,所以我認(rèn)為這里的翻譯不夠準(zhǔn)確(當(dāng)然源碼注解也沒有寫得很清楚),而且會(huì)引起歧義:trim()方法實(shí)際上trim掉了字符串兩端Unicode編碼小于等于32(\u0020)的所有字符。
System.out.println("' '的Unicode編碼為:" + (int)' '); // ' '的Unicode編碼為:32
trim()/substring()怎樣返回字符串對(duì)象?
再看另外一個(gè)問題:
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”,而在常量池中已經(jīng)確定存在這個(gè)”abc”這個(gè)String對(duì)象,那為何str1==str2不成立呢?
我們看trim()方法的最后一行:
return ((st > 0) || (len < value.length)) ? substring(st, len) : this;
也就是說,trim()方法實(shí)際上的行為并不是”去掉兩端的空白字符“,而是”截取中間的非空白字符“。
再看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); }
我們看到,當(dāng)實(shí)際發(fā)生了”截取“這個(gè)動(dòng)作的時(shí)候,因?yàn)榇颂師o(wú)法直接聲明一個(gè)String常量,即substring()無(wú)法像我們寫String str = “abc”這樣直接在常量池中創(chuàng)建對(duì)象,所以它返回的是一個(gè)new出來(lái)的對(duì)象,這個(gè)對(duì)象位于Heap內(nèi)存中。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
java.lang.UnsatisfiedLinkError: %1 不是有效的Win32應(yīng)用程序錯(cuò)誤解決
這篇文章主要給大家介紹了關(guān)于java.lang.UnsatisfiedLinkError: %1 不是有效的Win32應(yīng)用程序錯(cuò)誤的解決方法,文中介紹的非常詳細(xì),需要的朋友們可以參考學(xué)習(xí),下面來(lái)一起看看吧。2017-03-03Spring Boot項(xiàng)目中jar包在服務(wù)器上啟動(dòng)的正確姿勢(shì)
這篇文章主要給大家介紹了關(guān)于Spring Boot項(xiàng)目中jar包在服務(wù)器上啟動(dòng)的正確姿勢(shì),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-01-01JAVA 創(chuàng)建線程池的注意事項(xiàng)
這篇文章主要介紹了JAVA 創(chuàng)建線程池的注意事項(xiàng),文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07java實(shí)現(xiàn)的2048游戲完整實(shí)例
這篇文章主要介紹了java實(shí)現(xiàn)的2048游戲,結(jié)合完整實(shí)例形式分析了java實(shí)現(xiàn)2048游戲功能的相關(guān)數(shù)值運(yùn)算、swing組件布局、事件響應(yīng)等相關(guān)操作技巧,需要的朋友可以參考下2018-01-01詳解java一維數(shù)組及練習(xí)題實(shí)例
在本篇文章里小編給大家整理了關(guān)于java一維數(shù)組及練習(xí)題的相關(guān)知識(shí)點(diǎn)和實(shí)例代碼,有需要的朋友們跟著學(xué)習(xí)下。2019-07-07IDEA JAVA項(xiàng)目熱加載的實(shí)現(xiàn)步驟
熱加載可以使代碼修改后無(wú)須重啟服務(wù)器,就可以加載更改的代碼,本文主要介紹了IDEA JAVA項(xiàng)目熱加載的實(shí)現(xiàn)步驟,具有一定的參考價(jià)值,感興趣的可以了解一下2023-06-06Quartz實(shí)現(xiàn)JAVA定時(shí)任務(wù)的動(dòng)態(tài)配置的方法
這篇文章主要介紹了Quartz實(shí)現(xiàn)JAVA定時(shí)任務(wù)的動(dòng)態(tài)配置的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2018-07-07