你所不知道的Java效能優化之String!
Java效能優化之String字串優化
1.字串物件及其特點
Java中八大基本資料型別沒有String型別,因為String型別是Java對char陣列的進一步封裝。
String類的實現主要由三部分組成:char陣列,offset偏移量,String的長度。
String型別有三個基本特點:
-
不變性
-
不變性是指String物件一旦生成,則不能再對它進行改變。
-
不變性的作用在於當一個物件需要被多執行緒共享,並且頻繁訪問時,可以省略同步和鎖等待的時間,從而大幅提高系統效能。
針對常量池的優化
當兩個String物件擁有相同的值時,它們只引用常量池中的同一個拷貝。
類的final定義
作為final類的String物件在系統中不能有任何子類,這是對系統安全性的保護!
1.1 subString()方法的記憶體洩漏
關於這一點,在JDK的1.7及以後就已經解決了!
在1.7之前,subString()方法擷取字串只是移動了偏移量,擷取之後的字串實際上還是原來的大小。
現在,當使用subString()方法擷取字串時會把擷取後的字串拷貝到新物件。
1.2 字串分割與查詢
1、原始的String.split()
String.split()方法使用簡單,功能強大,支援正規表示式,但是,在效能敏感的系統中頻繁的使用這個方法是不可取的。
注意 * ^ : | . 這些符號記得\轉義
2、使用效率更高的StringTokenizer類分割字串
StringTokenizer類是JDK中提供的專門用來處理字串分割的工具類。構造方法:
public StringTokenizer(String str, String delim, boolean returnDelims)
其中str是要分割的字串,delim是分割符,returnDelims是否返回分隔符,預設false。
String s = "a;b;c"; StringTokenizer stringTokenizer = new StringTokenizer(s, ";", false); System.out.println(stringTokenizer.countTokens()); while (stringTokenizer.hasMoreTokens()) { System.out.println(stringTokenizer.nextToken()); }
3、最優化的字串分割方式
indexOf()方法是一個執行速度非常快的方法,subString()是採用了時間換空間技術,因此速度相對快。
public static List<String> mySplit(String str, String delim){ List<String> stringList = new ArrayList<>(); while(true) { int k = str.indexOf(delim); if (k < 0){ stringList.add(str); break; } String s = str.substring(0, k); stringList.add(s); str = str.substring(k+1); } return stringList; }//加入Java開發交流君樣:756584822一起吹水聊天
4、三種分割方法的對比與選擇
split()方法功能強大,但是效率最差;
StringTokenizer效能優於split方法,能用StringTokenizer就沒必要用split();
自己實現的分割演算法效能最好,但程式碼的可讀性和系統的可維護性最差,只有當系統效能成為主要矛盾時,才推薦使用該方法。
5、高效率的charAt方法
charAt(int index) 返回指定索引處的 char 值。功能和indexOf()相反,效率卻一樣高。
6、字串前後輟判斷
public boolean startsWith(String prefix) 測試此字串是否以指定的字首開始
public boolean endsWith(String suffix) 測試此字串是否以指定的字尾結束
這兩個Java內建函式效率遠遠低於charAt()方法。單元測試:
@Test public void test(){ String str = "hello"; if (str.charAt(0)=='h'&&str.charAt(1)=='e'){ System.out.println(true); } if (str.startsWith("he")){ System.out.println(true); } }//加入Java開發交流君樣:756584822一起吹水聊天
1.3 StringBuffer和StringBuilder
1、String常量的累加操作
String s = "123"+"456"+"789";
雖然從理論上說字串的累加的效率並不高,但該語句執行耗時為0;反編譯程式碼後,我們發現程式碼是
String s = "123456789";
顯然,是Java在編譯時做了充分的優化。因此,並沒有想象中那樣生成大量的String例項。
對於靜態字串的連線操作,Java在編譯時會進行徹底的優化,將多個連線操作的字串在編譯時合成一個單獨的長字串。
2、String變數累加的操作
String str = "hello"; str+="word"; str+="!!!"; //加入Java開發交流君樣:756584822一起吹水聊天
我們利用“+=”改變字串內容的值,實際上字串根本沒有改變。
當 str+="word" 時,堆記憶體開闢了word的記憶體空間和helloword的兩個記憶體空間(相當於例項化了兩個String物件),並把str的引用指向了helloword,原來的hello和word成為了垃圾被JVM回收。
3、concat() 連線字串
String的concat()是專門用於字串連線操作的方法,效率遠遠高於“+”或者“+=”。
4、StringBuffer和StringBuilder
不用多說了,就是為字串連線而生的,效率最高。不同的是,StringBuffer幾乎對所有的方法都做了同步,StringBuilder並沒有做任何同步,效率更高一些。只不過在多執行緒系統中,StringBuilder無法保證執行緒安全,不能使用。
5、容量引數
StringBuffer和StringBuilder的是對String的封裝,String是對char陣列的封裝。是陣列就有大小,就有不夠用的時候,不夠用只能擴容,也就是把原來的再複製到新的陣列中。合適的容量引數自然能夠減少擴容的次數,達到提高效率的目的。
在初始化時,容量引數預設是16個位元組。在構造方法中指定容量引數:
public StringBuilder(int capacity)
1.4 附一些實用的方法
判斷字串相等(忽略大小寫)
equalsIgnoreCase(String anotherString)
判斷是否存在子字串(返回布林型別)
contains(CharSequence s)
將指定字串連線到此字串的結尾
concat(String str)
使用指定的格式字串和引數返回一個格式化字串
format(String format, Object... args)
使用預設語言環境的規則將此 String 中的所有字元都轉換為小寫。
toLowerCase()
使用預設語言環境的規則將此 String 中的所有字元都轉換為大寫。
toUpperCase()
返回字串的副本,忽略前導空白和尾部空白。
trim()
使用給定的 replacement 替換此字串所有匹配給定的正規表示式的子字串。
String replaceAll(String regex, String replacement)
按字典順序比較兩個字串,不考慮大小寫。
int compareToIgnoreCase(String str)
如果引數字串等於此字串,則返回值 0;
如果此字串小於字串引數,則返回一個小於 0 的值;
如果此字串大於字串引數,則返回一個大於 0 的值。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69989885/viewspace-2745669/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 你所不知道的前端效能優化不完全手冊前端優化
- Java String之你不知道的事Java
- 你所不知道的 Typescript 與 Redux 型別優化TypeScriptRedux型別優化
- 你所不知道的Typescript與Redux型別優化TypeScriptRedux型別優化
- String字串效能優化的探究字串優化
- 關於Java你不知道的那些事之Java8新特性[HashMap優化]JavaHashMap優化
- 你不知道的Node.js效能優化,讀了之後水平直線上升Node.js優化
- Scala—Java的避難所之main(String[])JavaAI
- 效能測試工具Jmeter你所不知道的內幕JMeter
- 你所不知道的cssCSS
- 你所不知道的 POST
- 效能測試工具LoadRunner你所不知道的內幕
- Java 效能優化之——效能優化的過程方法與求職面經總結Java優化求職
- 你所不知道的虛擬化和雲端計算
- 你所不知道的JavaScript 二JavaScript
- 你所不知道的JavaScript(三)JavaScript
- java效能優化Java優化
- 你不知道的JavaScript——效能測試和調優JavaScript
- 效能優化漫談之七:效能優化的誤區優化
- 深入洞見:你所不知道的Java 物件序列化的5件事兒Java物件
- Go基礎之--位操作中你所不知道的用法Go
- MySQL 效能優化之索引優化MySql優化索引
- MySQL 效能優化之SQL優化MySql優化
- 你所不知道的 AI 進展AI
- 你所不知道的JavaScript陣列JavaScript陣列
- [java][效能優化]java高階開發必會的50個效能優化Java優化
- 效能優化之 NSDateFormatter優化ORM
- Android效能優化篇之計算效能優化Android優化
- Web效能優化之圖片優化Web優化
- 六、Android效能優化之UI卡頓分析之渲染效能優化Android優化UI
- 你所不知道的Python | 字串格式化的演進之路Python字串格式化
- 你不得不知道的 MySQL 優化原理MySql優化
- 提升----你所不知道的JavaScript系列(3)JavaScript
- 更多你所不知道的 Linux 命令Linux
- Android效能優化(七)之你真的理解ANR嗎?Android優化
- 效能優化小冊 - 提高網頁響應速度:優化你的 CDN 效能優化網頁
- 前端效能優化之效能測試前端優化
- Java效能優化的5個技巧Java優化