刚开始学习<em>Java</em>时,作为只会C语言的小白,就为其中的字符串操作而感到震撼。相比之下,C语言在字节数组中保存一个结尾的\0去表示字符串,想实现字符串拼接,还需要调用strcpy库函数或者自己手动去复制数组,非常麻烦,更
2021-05-20 12:31:02
一、前言
剛開始學習Java時,作為只會C語言的小白,就為其中的字元串操作而感到震撼。相比之下,C語言在位元組陣列中儲存一個結尾的 去表示字元串,想實現字元串拼接,還需要呼叫strcpy庫函數或者自己手動去複製陣列,非常麻煩,更別提其他複雜操作,而Java通過String類讓字元串操作變得十分簡單和方便。
除此之外,還有stringbuilder等這些類的輔助,那麼本文就從String,StringBuiler和StringBuffer的區別開始,去探討Java中的字元串操作。
二、String,StringBuiler和StringBuffer
2.1 String類
Java 提供了 String 類來創建和操作字元串。在源碼中可以看到,String類內部的實現也是一個位元組陣列,這個陣列是final類型的,因此String是不可變的物件,每次在對String類進行改變的時候都會生成一個新的string物件,然後將指針指向新的string物件。
2.2 StringBuiler 類
和 String 類不同的是,StringBuilder 類的物件能夠被多次的修改,並且不產生新的物件。這個特性的意義在於,如果我們進行大量的字元串操作,使用String類就會產生很大的效能消耗,而StringBuilder就可以避免這個問題。
2.3 StringBuffer 類
StringBuffer 和StringBuiler之間的最大不同在於 StringBuilder 的方法不是執行緒安全的。
由於 StringBuilder 相較於 StringBuffer 有速度優勢,所以多數情況下建議使用 StringBuilder 類。然而在應用程式要求執行緒安全的情況下,則必須使用 StringBuffer 類。
2.4 String,StringBuiler和StringBuffer的比較(對比C/C++)
三、各種字元串操作的效率測試
3.1 測試程式碼
@Testpublic void test() { int count = 100000; long startTime = System.currentTimeMillis(); String str = ""; for(int i = 0; i< count; i++){ str += i; } System.out.println("執行"+count+"次 String 耗時:"+ getRunTime(startTime)); startTime = System.currentTimeMillis(); StringBuilder stringBuilder = new StringBuilder(""); for (int i = 0; i < count; i++) { stringBuilder.append(i); } System.out.println("執行"+count+"次 StringBuilder 耗時:"+ getRunTime(startTime)); startTime = System.currentTimeMillis(); StringBuffer stringBuffer = new StringBuffer(""); for (int i = 0; i < count; i++) { stringBuffer.append(i); } System.out.println("執行"+count+"次 StringBuffer 耗時:"+ getRunTime(startTime));}
3.2 測試結果
執行100000次 String 耗時:32s執行100000次 StringBuilder 耗時:2ms執行100000次 StringBuffer 耗時:4ms
3.3 小結
可以看到String類的效能遠低於StringBuiler和StringBuffer,而StringBuiler在本次測試中比Stringbuffer提高了50%的效能
四、Java字元串和正則表示式
4.1 測試程式碼
@Testpublic void test0(){ //郵政編碼 String postCode = "[1-9]\d{5}"; //區號-座機號碼 String areaCode = "\d{3}-\d{8}|\d{4}-\d{7}"; //手機號碼 String phone = "(?:13\d|15\d|18\d)\d{5}(\d{3}|\*{3})"; String text = "郵政編碼:440834"+ "區號-座機號碼: 020-12345678"+ "手機號:13536373839"+ "郵政編碼:440833"+ "區號-座機號碼: 010-12345678"+ "手機號:13536373739"; Pattern p = Pattern.compile(postCode); Matcher m = p.matcher(text); System.out.println("文字中包含郵政編碼:"); while (m.find()){ System.out.println(m.group()); } p = Pattern.compile(areaCode); m= p.matcher(text); System.out.println("文字中包含區號-座機號碼:"); while (m.find()){ System.out.println(m.group()); } p = Pattern.compile(phone); m= p.matcher(text); System.out.println("文字中包含手機號:"); while (m.find()){ System.out.println(m.group()); }}
4.2 測試結果
文字中包含郵政編碼:440834123456135363440833123456135363文字中包含區號-座機號碼:020-12345678010-12345678文字中包含手機號:1353637383913536373739
五、總結
經過測試和比較,可以看到Java中同為字元串操作,但由於背後實現的原理不同,形成的效能差異也是十分巨大,相比之下,C/C++中的字元串操作效能更高。String類的效能遠低於StringBuiler和StringBuffer,而StringBuiler比Stringbuffer的效能稍微高一點。
對效能的探究,最終還是要回到使用場景,可以總結得出:
如果不涉及字元串操作,那麼String類是首選如果涉及的字元串操作沒有執行緒安全問題,那麼使用StringBuilder如果涉及的字元串操作存線上程安全問題,那麼使用StringBuffer。
好了,今天分享就到此,期待你的關注喔!
相關文章
刚开始学习<em>Java</em>时,作为只会C语言的小白,就为其中的字符串操作而感到震撼。相比之下,C语言在字节数组中保存一个结尾的\0去表示字符串,想实现字符串拼接,还需要调用strcpy库函数或者自己手动去复制数组,非常麻烦,更
2021-05-20 12:31:02
通过逃逸分析,<em>Java</em> Hotspot编译器能够分析出一个新的对象的引用的使用范围,从而决定是否要将这个对象分配到堆上。 逃逸分析是指分析指针动态范围的方法,它同编译器优化原理的指针分析和外形分析相关联。当
2021-05-20 12:30:58
学习技术想要了解某个知识点,我首先推荐的都是去官网查看。注解目前非常的流行,很多主流框架都支持注解,而且自己编写代码的时候也会尽量地去用注解,不是一时方便,而是代码更加简洁。注解(Annontation),<em>Java</em>5引入的
2021-05-20 12:30:51
那么,一份好的程序员简历,应该怎么写呢?本期,小编有幸采访了一些<em>JAVA</em>圈子里月薪过20K的行家们,来看看他们的简历是怎么写的。1、基本格调简洁明了 1)排版清晰 其实无论应聘哪个行业,简历排版的首要原则都是干净整洁
2021-05-20 12:30:49
为了给大家提供更加详细的体验,笔者大早上就拿<em>iPhone</em>12进行了更新体验,可以说更新的建议并不大。 一方面,<em>iPhone</em>12更新之后,流畅度有一点提升,但感知并不算强,而且功耗也变大了一些。 另一方面,这
2021-05-20 12:30:42
在<em>Linux</em>和Windows混合开发中经常遇到需要互相访问共享目录的情况,我经常遇到的情况是安装了windows虚拟机,需要从<em>linux</em>复制过去很多文件,那么在win上面开一个共享目录,然后从<em>linux</em>这里直接复
2021-05-20 12:30:30