自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

不再糾結(jié)Java中的String類(lèi)

開(kāi)發(fā) 后端
又是新的一月,又是各種總結(jié),先分享一下java中string的一些小專(zhuān)題吧,這部分比比較基礎(chǔ),但是也非常的有用。我發(fā)現(xiàn)很多面試官像中了邪一樣就愛(ài)問(wèn)這個(gè)。。string的種種,糾結(jié),希望這篇文章讓大家不再糾結(jié)。。

又是新的一月,又是各種總結(jié),先分享一下java中string的一些小專(zhuān)題吧,這部分比比較基礎(chǔ),但是也非常的有用。我發(fā)現(xiàn)很多面試官像中了邪一樣就愛(ài)問(wèn)這個(gè)。。string的種種,糾結(jié),希望這篇文章讓大家不再糾結(jié)。。

String是我們經(jīng)常用到的一個(gè)類(lèi)型,其實(shí)有時(shí)候覺(jué)得寫(xiě)程序就是在反復(fù)的操作字符串,這是C的特點(diǎn),在java中,jdk很好的封裝了關(guān)于字符串的操作。今天主要講的是三個(gè)類(lèi)String 、StringBuffer 、 StringBuilder .這三個(gè)類(lèi)基本上滿足了我們?cè)诓煌榫跋率褂米址男枨蟆?/p>

先說(shuō),第一個(gè)String。

JDK的解釋是 “Strings are constant; their values cannot be changed after they are created”也就是說(shuō)String對(duì)象一旦被創(chuàng)建就是固定不變的了(你一定有問(wèn)題,但請(qǐng)先等一等,耐心讀下去),這樣的一點(diǎn)好處就是可以多線程之間訪問(wèn),因?yàn)橹蛔x不寫(xiě)。

一般情況下我們以下面兩種方式創(chuàng)建一個(gè)String對(duì)象

   

兩種方式是有區(qū)別的,這和java的內(nèi)存管理有關(guān),前面已經(jīng)說(shuō)過(guò),string創(chuàng)建之后是不可變的,所以按照第一種方式創(chuàng)建的字符串會(huì)放在棧里,更確切的是常量池中,常量池就是用來(lái)保存在編譯階段確定好了大小的數(shù)據(jù),一般我們定義的int等基本數(shù)據(jù)類(lèi)型就保存在這里。

其具體的一個(gè)流程就是,編譯器首先檢查常量池,看看有沒(méi)有一個(gè)“string”,如果沒(méi)有則創(chuàng)建。如果有的話,則則直接把str1指向那個(gè)位置。

第二種創(chuàng)建字符串的方法是通過(guò)new關(guān)鍵字,還是java的內(nèi)存分配,java會(huì)將new的對(duì)象放在堆中,這一部分對(duì)象是在運(yùn)行時(shí)創(chuàng)建的對(duì)象。所以我們每一次new的時(shí)候,都會(huì)創(chuàng)建不同的對(duì)象,即便是堆中已經(jīng)有了一個(gè)一模一樣的。

寫(xiě)一個(gè)小例子

  1. String str1 = "string";  
  2.         String str4 = "string";  
  3.         String str2 = new String("string");  
  4.         String str3 = new String("string");  
  5.           
  6.         /*用于測(cè)試兩種創(chuàng)建字符串方式的區(qū)別*/ 
  7.         System.out.println(str1 == str4);  
  8.         System.out.println(str2 == str3);  
  9.         System.out.println(str3 == str1);  
  10.           
  11.         str3 = str3.intern(); //一個(gè)不常見(jiàn)的方法  
  12.         System.out.println(str3 == str1); 

這個(gè)的運(yùn)行結(jié)果是

true //解釋?zhuān)簝蓚€(gè)字符串的內(nèi)容完全相同,因而指向常量池中的同一個(gè)區(qū)域

false //解釋?zhuān)好恳淮蝞ew都會(huì)創(chuàng)建一個(gè)新的對(duì)象

false // 解釋?zhuān)?注意==比較的是地址,不僅僅是內(nèi)容

true //介紹一下intern方法,這個(gè)方法會(huì)返回一個(gè)字符串在常量池中的一個(gè)地址,如果常量池中有與str3內(nèi)容相同的string則返回那個(gè)地址,如果沒(méi)有,則在常量池中創(chuàng)建一個(gè)string后再返回。實(shí)際上,str3現(xiàn)在指向了str1的地址。

這就是讓人糾結(jié)的string了,現(xiàn)在你可以說(shuō)話了。。。很多人有這樣的疑問(wèn)就是既然string是不變的,那么為什么str1 + "some"是合法的,其實(shí),每次對(duì)string進(jìn)行修改,都會(huì)創(chuàng)建一個(gè)新的對(duì)象。

所以如果需要對(duì)一個(gè)字符串不斷的修改的話,效率是非常的低的,因?yàn)槎训暮锰幨强梢詣?dòng)態(tài)的增加空間,劣勢(shì)就是分配新的空間消耗是很大的,比如我們看下面的測(cè)試。

  1. long start = System.currentTimeMillis();  
  2.           
  3.         for(int i = 0; i < 50000; i++)  
  4.         {  
  5.             str1+= " ";  
  6.         }  
  7.           
  8.         long end = System.currentTimeMillis();  
  9.         System.out.println("the run time is "+(end -start)+" ms"); 

我的機(jī)器上運(yùn)行結(jié)果是the run time is 3538 ms 如果你把循環(huán)的次數(shù)后面再增加幾個(gè)0就會(huì)更慢。因?yàn)槊恳淮窝h(huán)都在創(chuàng)建心的對(duì)象,那么JDK如何解決這個(gè)問(wèn)題?

下面就要說(shuō)第二個(gè)類(lèi)StringBuffer。

StringBuffer是一個(gè)線程安全的,就是多線程訪問(wèn)的可靠保證,最重要的是他是可變的,也就是說(shuō)我們要操作一個(gè)經(jīng)常變化的字符串,可以使用這個(gè)類(lèi),基本的方法就是append(與string的concat方法對(duì)應(yīng))和insert方法,至于怎么使用,就不多講了,大家可以自己查看API。

  1. StringBuilder sb = new StringBuilder("string builder");  
  2.         StringBuffer sf = new StringBuffer("string buffer");  
  3.           
  4.         long start = System.currentTimeMillis();  
  5.           
  6.         for(int i = 0; i < 50000; i++)  
  7.         {  
  8.             //str1+= " ";  
  9.             sb.append(" ");  
  10.         }  
  11.           
  12.         long end = System.currentTimeMillis();  
  13.         System.out.println("the run time is "+(end -start)+" ms"); 

測(cè)試一下,這次只需要8ms,這就是效率。

那么接下來(lái),就要問(wèn)StringBuilder是干什么的,其實(shí)這個(gè)才是我們嘗使用的,這個(gè)就是在jdk 1.5版本后面添加的新的類(lèi),前面說(shuō)StringBuffer是線程同步的,那么很多情況下,我們只是使用一個(gè)線程,那個(gè)同步勢(shì)必帶來(lái)一個(gè)效率的問(wèn)題,StringBuilder就是StringBuffer的非線程同步的版本,二者的方法差不多,只是一個(gè)線程安全(適用于多線程)一個(gè)沒(méi)有線程安全(適用于單線程)。

其實(shí)看了一下jdk源代碼就會(huì)發(fā)現(xiàn),StringBuffer就是在各個(gè)方法上加上了關(guān)鍵字syncronized

    

  以上就是對(duì)三個(gè)字符串類(lèi)的一個(gè)總結(jié),總之不要在這上面糾結(jié)。。。。。。不想介紹太多的方法,總覺(jué)得那樣會(huì)把一篇博客弄成API文檔一樣,而且還非常的繁瑣。都是些體會(huì),希望有所幫助。起碼不要再糾結(jié),尤其是面試。。。。

本文完整源代碼:https://github.com/octobershiner/Java-Taste/tree/master/StringDemo

歡迎關(guān)注JavaTaste項(xiàng)目 https://github.com/octobershiner/Java-Taste

系列文章:http://www.cnblogs.com/octobershiner/archive/2012/03/17/2404154.html

【編輯推薦】

  1. Java中常見(jiàn)IO的讀寫(xiě)效率對(duì)比
  2. Java幾款性能分析工具的對(duì)比
  3. 棧的Java實(shí)現(xiàn)和棧的應(yīng)用舉例
  4. 實(shí)戰(zhàn)是硬道理:記Java技術(shù)面試
  5. Java設(shè)計(jì)模式:責(zé)任鏈
責(zé)任編輯:林師授 來(lái)源: octobershiner的博客
相關(guān)推薦

2023-09-18 08:56:57

StringJava

2015-07-08 09:28:46

Xcode代碼簽名

2015-10-14 11:11:06

右鍵菜單build 10565Windows 10

2011-06-01 14:01:45

JavaString

2012-03-09 10:02:29

Java

2020-10-23 07:43:31

String

2011-05-26 08:36:07

JDKJava

2020-05-09 12:16:12

中臺(tái)架構(gòu)工具

2009-06-12 13:48:13

數(shù)據(jù)類(lèi)型string類(lèi)Java教程

2022-03-18 09:42:54

JavaString

2022-11-26 08:03:57

StringJava類(lèi)

2009-06-12 13:28:23

Java類(lèi)中的包Java教程

2023-10-10 08:24:12

2023-01-05 11:34:46

PandasMerge方法

2015-10-12 08:56:27

Java不可變

2020-08-30 16:30:49

JavaScriptString Pad開(kāi)發(fā)

2024-12-30 11:12:59

C++靜態(tài)成員函數(shù)

2009-03-25 17:57:45

Linux新版企鵝

2009-06-30 15:18:10

StringBuildJava

2013-12-23 09:40:30

思科SDNACI
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)