Java字串分割與高效的charAt方法
阿新 • • 發佈:2019-02-03
說明:本文是閱讀《Java程式效能優化》(作者:葛一明)一書中關於字串分割與查詢一節的筆記。
一、字串分割
1、採用split方法分割字串
如下程式碼所示,對原始字串進行了10000次分割,在我的機器上用時大概3000ms左右。所以採用split方法對字串進行分割雖然簡單、功能強大,但是在效能敏感的系統中頻繁使用時效能是非常不好的。
2、使用效率更高的StringTokenizer類分割字串public class SplitDemo { public static void main(String[] args) { String str = null; StringBuffer sb = new StringBuffer(); for (int i = 0; i < 1000; i++) { sb.append(i).append(";"); } str = sb.toString(); long begin = System.currentTimeMillis(); for (int i = 0; i < 10000; i++) { str.split(";"); } long end = System.currentTimeMillis(); System.out.println(end - begin); } }
該類是JDK中提供的專門用來進行字串分割的工具類。採用該類來進行上例中同樣功能的字串分隔如下,在我的機器上用時大概1800ms左右,即使在這段程式碼中StringTokenizer物件不斷的被建立並銷燬,其效率也高於採用split方法來分割字串。
3、更優化的字串分割方式public class StringTokenizerDemo { public static void main(String[] args) { String str = null; StringBuffer sb = new StringBuffer(); for (int i = 0; i < 1000; i++) { sb.append(i).append(";"); } str = sb.toString(); long begin = System.currentTimeMillis(); StringTokenizer st = new StringTokenizer(str, ";"); for (int i = 0; i < 10000; i ++) { while (st.hasMoreTokens()) { st.nextToken(); } st = new StringTokenizer(str, ";"); } long end = System.currentTimeMillis(); System.out.println(end - begin); } }
可以自己設計演算法來完成高效的字串分割,如下程式碼所示,這裡採用了JDK提供的String類的indexOf方法與substring方法,在“Java substring方法與記憶體溢位”一節中我們知道substring方法採用了空間換取時間的技術,所以它的執行速度相對會很快,只要處理好記憶體溢位的問題即可;而indexOf也是一個執行非常快的方法。以下程式碼完成了上例同樣的功能,在我的機器上僅僅用了大概600ms左右的時間完成了10000次分割,遠遠超過了使用split方法或者StringTokenizer類的字串分割,但是這種方式的程式碼可讀性和系統的可維護性也是最差的。
二、高效的charAt方法public class CustomerSplitDemo { public static void main(String[] args) { String str = null; StringBuffer sb = new StringBuffer(); for (int i = 0; i < 1000; i++) { sb.append(i).append(";"); } str = sb.toString(); long begin = System.currentTimeMillis(); String temp = str; for (int i = 0; i < 10000; i++) { while (true) { String splitStr = null; // 保留擷取的字串 int index = temp.indexOf(";"); if (index < 0) { break; } splitStr = temp.substring(0, index); temp = temp.substring(index + 1); } temp = str; } long end = System.currentTimeMillis(); System.out.println(end - begin); } }
1、charAt方法與indexOf方法在效率上都是很高的方法。如下程式碼所示,判斷10000000次字串的開頭與結尾是否是“abc”,單純的使用charAt方法來實現,在我的機器上僅僅需要大概60ms左右的時間即可完成。
public class CharAtDemo {
public static void main(String[] args) {
String str = null;
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 1000; i++) {
sb.append(i).append(";");
}
str = sb.toString();
long begin = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
int len = str.length();
if (str.charAt(0) == 'a' && str.charAt(1) == 'b' && str.charAt(2) == 'c');
if (str.charAt(len - 3) == 'a' && str.charAt(len - 2) == 'b' && str.charAt(len - 1) == 'c');
}
long end = System.currentTimeMillis();
System.out.println(end - begin);
}
}
而使用JDK提供的startsWith與endsWith方法完成同樣次數的同樣的功能在我的機器上需要大概200ms左右的時間。