String是我們經常用到的一個類型
其實有時候覺得寫程序就是在反復的操作字符串
這是C的特點
在java中
jdk很好的封裝了關於字符串的操作
今天主要講的是三個類String
StringBuffer
StringBuilder
這三個類基本上滿足了我們在不同情景下使用字符串的需求
先說
第一個String
JDK的解釋是
Strings are constant; their values cannot be changed after they are created
也就是說String對象一旦被創建就是固定不變的了(你一定有問題
但請先等一等
耐心讀下去)
這樣的一點好處就是可以多線程之間訪問
因為只讀不寫
一般情況下我們以下面兩種方式創建一個String對象
兩種方式是有區別的
這和java的內存管理有關
前面已經說過
string創建之後是不可變的
所以按照第一種方式創建的字符串會放在棧裡
更確切的是常量池中
常量池就是用來保存在編譯階段確定好了大小的數據
一般我們定義的int等基本數據類型就保存在這裡
其具體的一個流程就是
編譯器首先檢查常量池
看看有沒有一個
string
如果沒有則創建
如果有的話
則則直接把str
指向那個位置
第二種創建字符串的方法是通過new關鍵字
還是java的內存分配
java會將new的對象放在堆中
這一部分對象是在運行時創建的對象
所以我們每一次new的時候
都會創建不同的對象
即便是堆中已經有了一個一模一樣的
寫一個小例子
這個的運行結果是
true //解釋
兩個字符串的內容完全相同
因而指向常量池中的同一個區域
false //解釋
每一次new都會創建一個新的對象
false // 解釋
注意==比較的是地址
不僅僅是內容
true //介紹一下intern方法
這個方法會返回一個字符串在常量池中的一個地址
如果常量池中有與str
內容相同的string則返回那個地址
如果沒有
則在常量池中創建一個string後再返回
實際上
str
現在指向了str
的地址
這就是讓人糾結的string了
現在你可以說話了…很多人有這樣的疑問就是既然string是不變的
那麼為什麼str
+
some
是合法的
其實
每次對string進行修改
都會創建一個新的對象
所以如果需要對一個字符串不斷的修改的話
效率是非常的低的
因為堆的好處是可以動態的增加空間
劣勢就是分配新的空間消耗是很大的
比如我們看下面的測試
我的機器上運行結果是the run time is
ms 如果你把循環的次數後面再增加幾個
就會更慢
因為每一次循環都在創建心的對象
那麼JDK如何解決這個問題?
下面就要說第二個類StringBuffer
StringBuffer是一個線程安全的
就是多線程訪問的可靠保證
最重要的是他是可變的
也就是說我們要操作一個經常變化的字符串
可以使用這個類
基本的方法就是append(與string的concat方法對應)和insert方法
至於怎麼使用
就不多講了
大家可以自己查看API
測試一下
這次只需要
ms
這就是效率
那麼接下來
就要問StringBuilder是干什麼的
其實這個才是我們嘗使用的
這個就是在jdk
版本後面添加的新的類
前面說StringBuffer是線程同步的
那麼很多情況下
我們只是使用一個線程
那個同步勢必帶來一個效率的問題
StringBuilder就是StringBuffer的非線程同步的版本
二者的方法差不多
只是一個線程安全(適用於多線程)一個沒有線程安全(適用於單線程)
其實看了一下jdk源代碼就會發現
StringBuffer就是在各個方法上加上了關鍵字syncronized
以上就是對三個字符串類的一個總結
總之不要在這上面糾結……不想介紹太多的方法
總覺得那樣會把一篇博客弄成API文檔一樣
而且還非常的繁瑣
都是些體會
希望有所幫助
起碼不要再糾結
尤其是面試…
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28892.html