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左右的时间。

你可能感兴趣的:(Java程序优化)