1. 程式人生 > >Java字串分割與高效的charAt方法

Java字串分割與高效的charAt方法

說明:本文是閱讀《Java程式效能優化》(作者:葛一明)一書中關於字串分割與查詢一節的筆記。

一、字串分割

1、採用split方法分割字串

如下程式碼所示,對原始字串進行了10000次分割,在我的機器上用時大概3000ms左右。所以採用split方法對字串進行分割雖然簡單、功能強大,但是在效能敏感的系統中頻繁使用時效能是非常不好的。

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);
	}

}
2、使用效率更高的StringTokenizer類分割字串

該類是JDK中提供的專門用來進行字串分割的工具類。採用該類來進行上例中同樣功能的字串分隔如下,在我的機器上用時大概1800ms左右,即使在這段程式碼中StringTokenizer物件不斷的被建立並銷燬,其效率也高於採用split方法來分割字串。

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);
	}

}
3、更優化的字串分割方式

可以自己設計演算法來完成高效的字串分割,如下程式碼所示,這裡採用了JDK提供的String類的indexOf方法與substring方法,在“Java substring方法與記憶體溢位”一節中我們知道substring方法採用了空間換取時間的技術,所以它的執行速度相對會很快,只要處理好記憶體溢位的問題即可;而indexOf也是一個執行非常快的方法。以下程式碼完成了上例同樣的功能,在我的機器上僅僅用了大概600ms左右的時間完成了10000次分割,遠遠超過了使用split方法或者StringTokenizer類的字串分割,但是這種方式的程式碼可讀性和系統的可維護性也是最差的。

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);
	}

}
二、高效的charAt方法

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左右的時間。