字元串操作java-ag真人国际官网
⑴ 淺談java中字元串的初始化(詳細圖解)
前言在深入學習字元串類之前,我們先搞懂jvm是怎樣處理新生字元串的。當你知道字元串的初始化細節後,再去寫strings="hello"或strings=newstring("hello")等代碼時,就能做到心中有數。
首先得搞懂字元串常量池的概念,下面進入正文吧。
常量池把經常用到的數據存放在某塊內存中,避免頻繁的數據創建與銷毀,實現數據共享,提高系統性能。
八種基礎數據類型除了float和double都實現了常量池技術。在近代的jdk版本中(1.7後),字元串常量池被實現在java堆內存中。
下面通過三行代碼讓大家對字元串常量池建立初步認識:
publicstaticvoidmain(string[]args){strings1="hello";strings2=newstring("hello");system.out.println(s1==s2);//false}先來看看第一行代碼strings1="hello";
直接通過雙引號(strings1="hello")聲明字元串的方式,虛擬機首先會到字元串常量池中查找該字元串是否已經存在。如果存在會直接返回該引用,如果不存在則會在堆內存中創建該字元串對象,然後到字元串常量池中注冊該字元串。
上面的代碼中(strings1="hello")虛擬機首先會到字元串常量池中查找是否有存在hello字元串對應的引用。發現沒有後會在堆內存創建hello字元串對象(內存地址0x0001),然後到字元串常量池中注冊地址為0x0001的hello對象,也就是添加指向0x0001的引用。最後把字元串對象返回給s1。
下面看strings2=newstring("hello");
當我們使用new關鍵字創建字元串對象的時候,jvm將不會查詢字元串常量池,它將會直接在堆內存中創建一個字元串對象,並返回給所屬變數。
所以s1和s2指向的是兩個完全不同的對象,判斷s1==s2的時候會返回false。
再來看下面的示例:
publicstaticvoidmain(string[]args){strings1=newstring("hello") newstring("world");s1.intern();strings2="helloworld";system.out.println(s1==s2);//true}第一行代碼strings1=newstring("hello") newstring("world");的執行過程是這樣子的:
依次在堆內存中創建hello和world兩個字元串對象;
然後把它們拼接起來(底層使用stringbuilder實現);
在拼接完成後會產生新的helloworld對象,這時變數s1指向新對象helloworld。
執行完第一行代碼後,內存是這樣子的:
第二行代碼s1.intern();
當調用intern()方法時,首先會去常量池中查找是否有該字元串對應的引用,如果有就直接返回該字元串;
如果沒有,就會在常量池中注冊該字元串的引用,然後返回該字元串。
由於第一行代碼採用的是new的方式創建字元串,所以在字元串常量池中沒有保存helloworld對應的引用,虛擬機會在常量池中進行注冊,注冊完後的內存示意圖如下:
第三行代碼strings2="helloworld";
首先虛擬機會去檢查字元串常量池,發現有指向helloworld的引用。然後把該引用所指向的字元串直接返回給所屬變數。
執行完第三行代碼後,內存示意圖如下:
如圖所示,s1和s2指向的是相同的對象,所以當判斷s1==s2時返回true。
總結:
當用new關鍵字創建字元串對象時,不會查詢字元串常量池;
當用雙引號直接聲明字元串對象時,虛擬機將會查詢字元串常量池。
說白了就是:字元串常量池提供了字元串的復用功能,除非我們要顯式創建新的字元串對象,否則對同一個字元串虛擬機只會維護一份拷貝。
反編譯代碼驗證字元串初始化操作下面我們再來看一個示例:
publicclassmain{publicstaticvoidmain(string[]args){strings1="hello";strings2="world";strings3=s1 s2;strings4="helloworld";system.out.println(s3==s4);}}首先第一行和第二行是常規的字元串對象聲明,它們分別會在堆內存創建字元串對象,並會在字元串常量池中進行注冊。
影響我們做出判斷的是第三行代碼strings3=s1 s2;,我們不知道s1 s2在創建完新字元串helloworld後是否會在字元串常量池進行注冊。
簡單點說:我們不知道這行代碼是以雙引號形式聲明字元串,還是用new關鍵字創建字元串。
那麼我們看下這端代碼的反編譯後的代碼:
psd:codejavase argetclassesdemo>javap-c.main.classcompiledfrom"main.java"publicclassdemo.main{publicdemo.main();code:0:aload_01:invokespecial#1//methodjava/lang/object."直接看重點:
21:invokevirtual#7//methodjava/lang/stringbuilder.tostring:()ljava/lang/string;
24:astore_3
虛擬機調用stringbuilder的tostring()方法獲得字元串helloworld,並存放至s3。
下面是我們追蹤stringbuilder的tostring()方法源碼:
@overridepublicstringtostring(){//createa,don'tsharethearrayreturnnewstring(value,0,count);}通過以上源碼可以看出:s3是通過new關鍵字獲得字元串對象的。
回到題目,也就是說字元串常量表中沒有存儲helloworld的引用,當s4以引號的形式聲明字元串時,由於在字元串常量池中查不到相應的引用,所以會在堆內存中新創建一個字元串對象。所以s3和s4指向的不是同一個字元串對象,結果為false。
總結閱讀完本文,相信你對於字元串的初始化的了解又更上一層了。關注我,一個專注分享java知識的新時代農民工。
作者:初念初戀
⑵ java工具類(一)guava操作字元串
在java編程中,處理字元串是一個常見任務,從簡單的空值判斷到復雜的拆分和連接操作,都需要高效、簡便的解決方案。為簡化這類任務,google開發了guava庫,提供豐富的集合工具和高效字元串處理功能。本文將深入探討guava庫的字元串操作能力,重點關注連接器、拆分器、字元匹配器、字元集和大小寫格式工具。
guava連接器(joiner)是一個強大的字元串連接工具,能夠優雅地處理空值問題。其使用方式分為三步:使用`on`方法設置連接符,調用`usefornull`方法為`null`值設定默認處理,最後使用`join`方法處理集合。例如:
java
joiner joiner = joiner.on(", ");
string result = joiner.join(arrays.aslist("apple", null, "banana"));
guava拆分器(splitter)允許以模式、字元、字元串或字元匹配器進行復雜拆分,返回`iterable`對象。其創建和配置過程同樣遵循不可變設計原則,確保線程安全。
字元匹配器(charmatcher)則提供了一種簡單而強大的方式來處理特定類型的字元,如數字或空白字元。它實現了一個布爾判斷介面,並提供了多種方法來操作匹配字元,如修剪、折疊、移除、保留等。
charsets為java平台提供的六種標准字元集提供了常量引用,確保了跨平台兼容性。使用這些常量而非名稱獲取實例能避免潛在的不兼容性問題。
大小寫格式(caseformat)工具用於方便地在不同ascii大小寫規范間轉換字元串,支持多種格式。例如,轉換字元串以適應編程語言的命名規范。
總結而言,guava的字元串處理工具集不僅簡化了常見字元串操作,還提供了高性能、靈活的解決方案,適用於大規模數據處理。在使用時,需根據具體需求和場景合理選擇工具和參數,以實現性能優化。guava庫的高效設計和豐富功能,為java開發者提供了強大的支持,有助於提高開發效率和代碼質量。
⑶ java字元串格式化和工具類使用
前言我們在做項目時候經常需要對字元串進行處理,判斷,操作,所以我就總結了一下java字元串一些常用操作,和推薦比較好用我在自用的工具類,畢竟有輪子我們自己就不用重復去寫了,提供開發效率,剩下的時間就去約女朋友吧哈哈哈!!!!
我們知道平時我們都會做字元串拼接列印操作,單還是在用?號嘛,那樣就很low為力顯示逼格,使用format操作很有必要?
string類的format()方法用於創建格式化的字元串以及連接多個字元串對象,制定字元串格式和參數生成格式化的字元串。顯示不同轉換符實現不同數據類型到字元串的轉換
測試用例:
@testpublicvoida(){stringstr="";str=string.format("hi,%s","王力");system.out.println(str);str=string.format("hi,%s:%s.%s","王南","王力","王張");system.out.println(str);system.out.printf("字母a的大寫是:%c%n",'a');system.out.printf("3>7的結果是:%b%n",3>7);system.out.printf("100的一半是:%d%n",100/2);system.out.printf("100的16進制數是:%x%n",100);system.out.printf("100的8進制數是:%o%n",100);system.out.printf("50元的書打8.5折扣是:%f元%n",50*0.85);system.out.printf("上面價格的16進制數是:%a%n",50*0.85);system.out.printf("上面價格的指數表示:%e%n",50*0.85);system.out.printf("上面價格的指數和浮點數結果的長度較短的是:%g%n",50*0.85);system.out.printf("上面的折扣是%d%%%n",85);system.out.printf("字母a的散列碼是:%h%n",'a');}列印結果
._________/\/___'_____(_)______\\(()\___|'_|'_||'_/_`|\\\/___)||_)|||||||(_||))))'|____|.__|_||_|_||_\__,|////=========|_|==============|___/=/_/_/_/::springboot::(v2.4.7)2021-09-1010:42:07infobackground-preinitorg.hibernate.validator.internal.util.versionhv000001:hibernatevalidator6.1.7.final2021-09-1010:42:.8.0_202onxiangyongdemacbook-pro.localwithpid46281(startedbyxiangyongin/users/xiangyong/selfproject/project/kmall/kmall-api)2021-09-1010:42::test,mptest__|___|_.____|_|||/|_)(_|||_|_)||_|_/|3.4.12021-09-1010:42:.755seconds(jvmrunningfor8.519)hi,王力hi,王南:王力.王張字母a的大寫是:a3>7的結果是:false100的一半是:50100的16進制數是:64100的8進制數是:14450元的書打8.5折扣是:42.500000元上面價格的16進制數是:0x1.54p5上面價格的指數表示:4.250000e 01上面價格的指數和浮點數結果的長度較短的是:42.5000上面的折扣是85%字母a的散列碼是:41更多格式進入參考這里
equals兩個字元串做比較,當然這里比較的話就不得不提老生常談的問題,==和equals區別
首先的區別是,equals是方法,而==是操作符;
equals比較的是兩個字元串內容而不是引用
==在比較對象時比較的是引用地址是否相同,在比較基本類型時比較的是其內容
@testpublicvoida(){//s1與s2不是同一個對象strings1=newstring("aaa");strings2=newstring("aaa");system.out.println(s1==s2);//falsesystem.out.println(s1.equals(s2));//true//s5與s6是基本數據類型strings5="aaa";strings6="aaa";system.out.println(s5==s6);//truesystem.out.println(s5.equals(s6));//true//s3和s4是同一個地址的引用strings3=newstring("aaa");strings4=s3;system.out.println(s3==s4);//truesystem.out.println(s3.equals(s4));//true}注意我們看到s5==s6是true而s1==s2是false,因為s5和s6是基本數據類型此時比較的是值,s1和s2是對象比較的是引用所以是不同兩個string對象比較引用
這里涉及到基本數據類型:
java中有8種基本數據類型(字母開頭小寫),即boolean、byte、short、char、int、float、long、double,基本數據類型不是對象,放在堆棧中,用完就銷毀,訪問速度快。而對象放在堆中。如果必須用到對象java針對每種基本數據類型提供了包裝類,即boolean、byte、short、character、integer、float、long、double(開頭大寫)等。
詳細深入參考點擊進入
tostring返回當前string對象的字元串表示形式,一般用於列印對象信息方便快捷,所有類都繼承object,任何類,都可以重寫tostring方法
工具類hutool借用官方引用:
hutool是一個小而全的java工具類庫,通過靜態方法封裝,降低相關api的學習成本,提高工作效率,使java擁有函數式語言般的優雅,讓java語言也可以「甜甜的
點擊進入官網導航強烈推薦
已發布maven中央倉庫,多麼模塊可以單獨引用某一個模塊,也可以引用全部,
包含組件如下:
分的比較·散亂單,應為不是專門的工具庫,但是用起來還是挺不錯的使用頻率最高的框架。有很多實用的工具類並沒有全部列出來,只列出了最基礎的一部分,感興趣的小夥伴,可以看官方的api進行更深入的學習
apachecommons有很多子項目,常用的項目如下
詳細使用參考這里點擊進入
作者:kenx
⑷ java中字元串如何去除最後一個字元
在java中,處理字元串並移除最後一個字元的操作相當直接,主要藉助於string類的兩個方法:substring()和length()。以下是詳細的步驟:
1.使用substring()方法:這個方法有兩個參數,第一個參數是開始截取的索引(包括該位置的字元),第二個參數是截止但不包括的索引。當你想要移除最後一個字元時,可以設置開始索引為字元串長度減一,然後截取到原長度。例如:
java
stringoriginal="example";
intlastcharindex=original.length()-1;
stringresult=original.substring(0,lastcharindex);
2.利用length()方法獲取字元串長度:這個方法返回字元串中的字元數,包括空格和特殊字元。通過減一,我們可以得到最後一個字元的位置。
3.如果你希望移除字元串尾部的特定字元,而非僅最後一個字元,可以考慮使用trim()方法。rtrim()和trimend()是trim()方法的變體:
-rtrim()會移除字元串末尾的空格或特定字元數組中的字元。
-trimend()接受一個字元數組作為參數,移除數組中每個字元的尾部出現。
以下是使用這些方法的實例:
java
stringstr="example@trimme";
stringtrimmed=str.trim();
stringrtrimmed=str.rtrim('@');//或者str.trimend('@');
通過上述方法,你可以有效地在java中移除字元串的最後一個字元或尾部特定字元。