5分鐘快速了解String.trim()到底做了什么事
前言
項目中遇到用String.trim()的地方,點進去看了trim()源碼,以前一直以為trim()的作用只是去除字符串中的首尾的“空格”符,但是源碼看下來,好像這個說法不太準確呢。
搞技術(shù)嘛,嚴謹一些,在這記錄一下,大佬們也瞅瞅哈~
說我們認知的trim()
說到String.trim() 函數(shù) ,就像前言說的一樣,我的認知它就是搞首尾空格用的,雖然這個說法也沒錯哈。
那這都說到這了,不試試看說不過去對吧:
String str = " Hello World "; System.out.println(str.length()); System.out.println(str.trim().length());
小字都是旁白:“搞掉了嗎?看樣子是搞掉了?!?所以說它去除首尾空格沒毛病哈。
復(fù)習(xí)一個小概念
Java 語言規(guī)范規(guī)定,Java 的 char 類型是 UTF-16 的 code unit,也就是一定是16位(2字節(jié))。
char(字符)的范圍是:0-65535 or(\u0000~\uFFFF)
看圖看圖!
知乎一個大佬答主的回答:Java 語言中一個字符占幾個字節(jié)?
我怎么會讓各位大佬去看別的鏈接呢,當(dāng)然,如果有時間的話,我會單獨整理一篇奉上。
養(yǎng)成一個好習(xí)慣
養(yǎng)成一個好習(xí)慣,多看看源碼,其實很多時候,源碼里的注釋或者源碼流程中就已經(jīng)很好的解釋了。
而我們往往很多時候都不愿意去看源碼。
小字都是旁白:“源碼都是英文,看著都頭疼。堅持看完,可解偏頭疼喲~”
當(dāng)然,即使大佬你真的不愿意去看源碼。大佬您這都賞臉點進來了,自然由我來說給您聽。
在 JDK 1.8 中trim()的源碼注釋里其實已經(jīng)解釋的很清楚了:
1. 刪除任何前置和后置空格;
2. 如果String對象表示一個空字符,則返回對這個String對象的引用;
總結(jié):【trim()大佬說了:你這有一個二五崽(空格),我換一個新崽給你】
3. 如果String對象表示的字符的首和尾字符的編碼都大于'\u0020'(空格字符),則返回對這個String對象的引用;
總結(jié):【trim()大佬說了:空格前后有兄弟,我不搞你】
4. 如果String字符串中沒有編碼大于'\u0020'的字符,則返回一個表示空字符串的string對象;
總結(jié):【trim()大佬說了:看你可憐,給你送你一個新崽(新String對象,空的,長度為0的)】
5. 假設(shè) k 是代碼大于'\u0020'的字符串中第一個字符的索引,假設(shè) m 是代碼大于''\u0020'的字符串中最后一個字符的索引。返回一個表示該字符串的子字符串,該子字符串以下標 k 處的字符開始,以下標 m 處的字符結(jié)束。即 substring(k, m + 1)。
總結(jié):【trim()大佬說了:前后的二五崽(小于'\u0020')我都帶走,老實崽和有兄弟的二五仔都給你留下了】
6. 如果使用trim()后的字符串長度不等于使用前的長度,就返回一個新崽(新String對象)給你;如果等于,就還給你以前的崽(原String對象)。
總結(jié):【trim()大佬說了:不等于 -> 你這個崽有貓膩(長度變了),給你換一個新崽;等于 -> 你這個崽沒得問題,帶回去好好養(yǎng)起】
動起來,不瞎掰
示例 1-6 對應(yīng)了上面6條 trim()
源碼說明。實踐是實現(xiàn)真理的唯一標準實踐是實現(xiàn),大佬們,我直接開整了哈。
示例1
/** * 1.刪除任何前置和后置空格; */ @Test public void str1(){ String str = " Hello World "; System.out.println(str.length()); System.out.println("trim():" + str.trim().length()); }
示例2
/** * 你這有一個二五崽(空格),我換一個新崽給你 */ @Test public void str2(){ // 如果String對象表示一個空字符,則返回對這個String對象的引用; String str1 = " "; System.out.println(str1.length()); String str2 = str1.trim(); System.out.println("trim()->" + str2.length()); System.out.println(str1 == str2); }
示例3
/** * 空格前后有兄弟,我不搞你 */ @Test public void str3(){ String str1 = "aaa bbb ccc"; System.out.println(str1.length()); String str2 = str1.trim(); System.out.println(str2.length()); }
示例4
/** * 看你可憐,給你送你一個新崽(新String對象,空的,長度為0的) */ @Test public void str4(){ // 你有32個崽; char[] chars = new char[32]; for (int i = 0; i < 32; i++) { chars[i] = (char) i; } String oldStr = new String(chars); System.out.println(oldStr.length()); // 可惜是32個二五崽 String newStr = oldStr.trim(); System.out.println(newStr.trim().length()); System.out.println(oldStr == newStr); }
示例5
/** * 假設(shè) k 是代碼大于'\u0020'的字符串中第一個字符的索引, * 假設(shè) m 是代碼大于''\u0020'的字符串中最后一個字符的索引。 * 返回一個表示該字符串的子字符串,該子字符串以下標 k 處的 * 字符開始,以下標m處的字符結(jié)束。即substring(k, m + 1)。 */ @Test public void str5(){ // 先準備8個崽 char[] chars = new char[8]; // 3個二五崽 for (int i = 0; i < 3; i++) { chars[i] = (char) i; } chars[3] = 65; chars[4] = 66; // 二五崽(小于空格符,空格符是32) chars[5] = 31; chars[6] = 68; // 二五崽(小于空格符,空格符是32) chars[7] = 21; String oldStr = new String(chars); System.out.println("oldStr.length():" + oldStr.length()); System.out.println("oldStr:" + oldStr); String newStr = oldStr.trim(); System.out.println("newStr.length():" + newStr.length()); System.out.println("newStr:" + newStr); }
示例6
/** * 不等于 -> 你這個崽有貓膩(長度變了),給你換一個新崽;等于 -> 你這個崽沒得問題,帶回去好好養(yǎng)起 */ @Test public void str6(){ // 準備5個崽 char[] chars = new char[5]; // 3個二五崽 for (int i = 0; i < 3; i++) { chars[i] = (char) i; } chars[3] = 65; chars[4] = 66; String str1 = new String(chars); String str2 = "ABCDE"; String newStr1 = str1.trim(); String newStr2 = str2.trim(); System.out.println("str1.length():" + str1.length()); System.out.println("newStr1.length():" + newStr1.length()); System.out.println(str1 == newStr1); System.out.println("=========================\n"); System.out.println("str2.length():" + str2.length()); System.out.println("newStr2.length():" + newStr2.length()); System.out.println(str2 == newStr2); }
5分鐘直接看這里
trim()
到底做了什么事
- 去除 String 中的首尾空格;
- 無法去除字符串中間含有空格的;
- 準確說實際去除的是小于十進制32(32就是空格,可以去看Ascii表)的所有字符。
- 當(dāng) String 中全是小于32的字符時,返回一個新的字符給你。
- String.trim() 長度變化就是新對象,無變化就還是自己。
trim()方法可以去除的字符明細可以通過以下函數(shù)進行輸出:
public class StringTest { public static void main(String[] args) { char[] chars = new char[20]; chars[0] = ‘\u0000'; chars[1] = ‘\u0001'; chars[2] = ‘\u0002'; chars[3] = ‘\u0003'; chars[4] = ‘\u0004'; chars[5] = ‘\u0005'; chars[6] = ‘\u0006'; chars[7] = ‘\u0007'; chars[8] = ‘\u0008'; chars[9] = ‘\u0009'; chars[10] = ‘\u0010'; chars[11] = ‘\u0012'; chars[12] = ‘\u0013'; chars[13] = ‘\u0014'; chars[14] = ‘\u0015'; chars[15] = ‘\u0016'; chars[16] = ‘\u0017'; chars[17] = ‘\u0018'; chars[18] = ‘\u0019'; chars[19] = ‘\u0020'; for (int i = 0; i < chars.length; i++) { System.out.print("(" + i + ")" + chars[i] + " "); if (i != 0 && i % 5 == 0) { System.out.println(); } } } }
輸出如下:
總結(jié)
到此這篇關(guān)于5分鐘快速了解String.trim()到底做了什么事的文章就介紹到這了,更多相關(guān)5分鐘了解String.trim()內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
支票金額大寫轉(zhuǎn)換示例(金額大寫轉(zhuǎn)換器)
這篇文章主要介紹了支票金額大寫轉(zhuǎn)換示例(金額大寫轉(zhuǎn)換器),需要的朋友可以參考下2014-02-02Java使用IOC控制反轉(zhuǎn)的三種設(shè)計模式詳解
這篇文章主要為大家詳細介紹了Java使用IOC控制反轉(zhuǎn)的三種設(shè)計模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-10-10mybatis-plus阻止全表更新與刪除的實現(xiàn)
BlockAttackInnerInterceptor 是mybatis-plus的一個內(nèi)置攔截器,用于防止惡意的全表更新或刪除操作,本文主要介紹了mybatis-plus阻止全表更新與刪除的實現(xiàn),感興趣的可以了解一下2023-12-12Java轉(zhuǎn)換解析中間帶有 “T“和“Z“ 的時間格式
這篇文章主要給大家介紹了關(guān)于Java轉(zhuǎn)換解析中間帶有 “T“和“Z“ 的時間格式,相信很多小伙伴在時間格式轉(zhuǎn)換的時候非常頭疼,文中通過代碼示例介紹的非常詳細,需要的朋友可以參考下2024-01-01SpringBoot實現(xiàn)全局異常處理方法總結(jié)
在項目開發(fā)中出現(xiàn)異常時很平常不過的事情,我們處理異常也有很多種方式。本文將詳細為大家講解SpringBoot實現(xiàn)全局異常處理幾種方法,感興趣的可以學(xué)習(xí)一下2022-03-03springboot中關(guān)于classpath:路徑使用及說明
這篇文章主要介紹了springboot中關(guān)于classpath:路徑使用及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09Java實現(xiàn)刪除排序鏈表中的重復(fù)元素的方法
這篇文章主要介紹了Java實現(xiàn)刪除排序鏈表中的重復(fù)元素的方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02