StringTokenizer

之前没接触过StringTokenizer,看上去类名很长,仿佛很牛13似的。最近了解了一下

引用

  StringTokenizer 类允许应用程序将字符串分解为标记


也就是分解字符串用的
让我们来看一个简单的例子

Java代码
  1. StringTokenizer st =  new  StringTokenizer( "this is a test" );  
  2. while  (st.hasMoreTokens()) {  
  3.     System.out.println(st.nextToken());  
  4. }  
     StringTokenizer st = new StringTokenizer("this is a test");
     while (st.hasMoreTokens()) {
         System.out.println(st.nextToken());
     }


出去结果如下

Java代码
  1. this   
  2. is  
  3. a  
  4. test  
     this
     is
     a
     test


这种不带参数的StringTokenizer使用的分隔符是/t/n/r/f,即空白字符、制表符、换行符、回车符和换页符。
ok,StringTokenizer还提供了另一种构造方法,StringTokenizer(String str, String delim)
从名字上看,可以知道,我们可以自定义delimiter。那么,这个delimiter是不是可以为正则表达式呢?满怀期待的试验一下

Java代码
  1. String input =  "This is just a test" ;  
  2. //设想的delimiter可以为正则表达式   
  3. StringTokenizer st = new  StringTokenizer(input, "//s{1}" );  
  4. while (st.hasMoreTokens()){  
  5.   System.out.println(st.nextToken());  
  6. }  
   String input = "This is just a test";
   //设想的delimiter可以为正则表达式
   StringTokenizer st = new StringTokenizer(input,"//s{1}");
   while(st.hasMoreTokens()){
     System.out.println(st.nextToken());
   }


本以为结果会是

Java代码
  1. this   
  2. is  
  3. a  
  4. test  
     this
     is
     a
     test


哪知一看,结果为

Java代码
  1.   Thi  
  2.  i  
  3.  ju  
  4. t a te  
  5. t  
  Thi
 i
 ju
t a te
t


可见,StringTokenizer的delimeter不可以为正则表达式
替代方法?
首先,来看String的split方法

Java代码
  1. String input =  "This is just a test" ;  
  2. String [] str = input.split("//s{1}" );  
  3. for ( int  i= 0 ;i
  4.   System.out.println(str[i]);  
  5. }  
  String input = "This is just a test";
  String [] str = input.split("//s{1}");
  for(int i=0;i


输出结果为

Java代码
  1. this   
  2. is  
  3. a  
  4. test  
     this
     is
     a
     test


ok,正确。String的split方法接受的参数可以为正则表达式。
我们可以看一下split方法的定义

Java代码
  1. public  String[] split(String regex) {  
  2.       return  split(regex,  0 );  
  3. }  
  public String[] split(String regex) {
        return split(regex, 0);
  }


其实这个参数他们就是按正则表达式来对待的。(哎,我一直以为只能是字符呢 )

接着来看Scanner的表现。

引用

一个可以使用正则表达式来解析基本类型和字符串的简单文本扫描器

 

Java代码
  1. Scanner scanner =  new  Scanner(input);  
  2. scanner.useDelimiter("//s{1}" );  
  3. while (scanner.hasNext()){  
  4. ystem.out.println(scanner.next());  
  5. }  
  Scanner scanner = new Scanner(input);
  scanner.useDelimiter("//s{1}");
  while(scanner.hasNext()){
	System.out.println(scanner.next());
  }


同样的,通过设置Delimiter(可以为正则表达式),我们可以很轻松的拆分字符串
输出结果为

Java代码
  1.   This  
  2. is  
  3. just  
  4. a  
  5. test  
  This
is
just
a
test


另外,还可以使用Pattern类的split方法,我觉得这个和String的split方法差不多。(Pattern类主要不是用在拆分字符串,而是在正则表达式的应用那里)

Java代码
  1. Pattern pattern = Pattern.compile( "//s{1}" );  
  2. str = pattern.split(input);  
  3. for ( int  i= 0 ;i
  4. ystem.out.println(str[i]);  
  5. }  
  Pattern pattern = Pattern.compile("//s{1}");
  str = pattern.split(input);
  for(int i=0;i


结果同样为

Java代码
  1.   This  
  2. is  
  3. just  
  4. a  
  5. test  
  This
is
just
a
test



好了,现在已经知道的就有三种方式来代替StringTokenizer了,并且由于StringTokenizer只能做一些很简单的拆分,远不能适应现在的要求,所以,StringTokenizer,你可以放心的撤退了,远离历史舞台吧。
其实sun也知道这个

sun 写道

StringTokenizer is a legacy class that is retained for
* compatibility reasons although its use is discouraged in new code. It is
* recommended that anyone seeking this functionality use the split
* method of String or the java.util.regex package instead.


ps:那个老帖子是04年的。也许那会还没有这么多的替代方法。
不过5年过去了。StringTokenizer就不要再用了。

 

 

 

 

 

 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

dennis_zane 写道
kaka2008 写道
dennis_zane 写道
不知道你有没有考察过性能。。如果不需要正则,并且切分非常频繁的话,StringTokenizer快上很多。


没有考察过性能。
有时间了,我测试一下。然后补充。
不过不知道不需要正则的切分用处多不多。


很多的是,比如我过去干过的用StringTokenizer来切分memcached文本协议,就比用Pattern.split快多了。



我简单的测试了下。的确是它最快。
不知道我的测试结果科学不科学,请指教

 

 

 

 

 

 

////////////////////////////////////////////////////////////////////

 

Java代码
  1.         public   static   void  main(String [] args){  
  2.     long  start = System.currentTimeMillis();  
  3.     for ( int  i= 0 ;i< 100000 ;i++){  
  4.         test1();  
  5.     }  
  6.     long  end = System.currentTimeMillis();  
  7.     System.out.println("StringTokenzier: " +(end-start));  
  8.       
  9.     start = System.currentTimeMillis();  
  10.     for ( int  i= 0 ;i< 100000 ;i++){  
  11.         test2();  
  12.     }  
  13.     end = System.currentTimeMillis();  
  14.     System.out.println("Scanner: " +(end-start));  
  15.       
  16.     start = System.currentTimeMillis();  
  17.     for ( int  i= 0 ;i< 100000 ;i++){  
  18.         test3();  
  19.     }  
  20.     end = System.currentTimeMillis();  
  21.     System.out.println("String: " +(end-start));  
  22.       
  23.     start = System.currentTimeMillis();  
  24.     for ( int  i= 0 ;i< 100000 ;i++){  
  25.         test4();  
  26.     }  
  27.     end = System.currentTimeMillis();  
  28.     System.out.println("Pattern: " +(end-start));  
  29. }  
  30.        //用StringTokenizer   
  31. public   static   void  test1(){  
  32.     String input = "This is 1 just a test" ;  
  33.     StringTokenizer st = new  StringTokenizer(input);  
  34.     while (st.hasMoreTokens()){  
  35.         String s = st.nextToken();  
  36.     }  
  37. }  
  38. //用Scanner的方法   
  39. public   static   void  test2(){  
  40.     String input = "This is 1 just a test" ;  
  41.     Scanner scanner = new  Scanner(input);  
  42.     scanner.useDelimiter(" " );  
  43.     while (scanner.hasNext()){  
  44.         String s = scanner.next();  
  45.     }  
  46. }  
  47. //用String的split方法   
  48. public   static   void  test3(){  
  49.     String input = "This is 1 just a test" ;  
  50.     String [] str = input.split(" " );  
  51.     for ( int  i= 0 ;i
  52.         String s = str[i];  
  53.     }  
  54. }  
  55. //用Pattern的方法   
  56. public   static   void  test4(){  
  57.     Pattern pattern = Pattern.compile(" " );  
  58.     String input = "This is 1 just a test" ;  
  59.     String [] str = pattern.split(input);  
  60.     for ( int  i= 0 ;i
  61.         String s = str[i];  
  62.     }  
  63. }  
        public static void main(String [] args){
		long start = System.currentTimeMillis();
		for(int i=0;i<100000;i++){
			test1();
		}
		long end = System.currentTimeMillis();
		System.out.println("StringTokenzier: "+(end-start));
		
		start = System.currentTimeMillis();
		for(int i=0;i<100000;i++){
			test2();
		}
		end = System.currentTimeMillis();
		System.out.println("Scanner: "+(end-start));
		
		start = System.currentTimeMillis();
		for(int i=0;i<100000;i++){
			test3();
		}
		end = System.currentTimeMillis();
		System.out.println("String: "+(end-start));
		
		start = System.currentTimeMillis();
		for(int i=0;i<100000;i++){
			test4();
		}
		end = System.currentTimeMillis();
		System.out.println("Pattern: "+(end-start));
	}
        //用StringTokenizer
	public static void test1(){
		String input = "This is 1 just a test";
		StringTokenizer st = new StringTokenizer(input);
		while(st.hasMoreTokens()){
			String s = st.nextToken();
		}
	}
	//用Scanner的方法
	public static void test2(){
		String input = "This is 1 just a test";
		Scanner scanner = new Scanner(input);
		scanner.useDelimiter(" ");
		while(scanner.hasNext()){
			String s = scanner.next();
		}
	}
	//用String的split方法
	public static void test3(){
		String input = "This is 1 just a test";
		String [] str = input.split(" ");
		for(int i=0;i


运行了五次。输出结果如下:

Java代码
  1.  StringTokenzier:  110   
  2. Scanner: 3281   
  3. String: 453   
  4. Pattern: 438   
  5.   
  6. StringTokenzier: 109   
  7. Scanner: 3297   
  8. String: 453   
  9. Pattern: 438   
  10.   
  11. StringTokenzier: 110   
  12. Scanner: 3265   
  13. String: 485   
  14. Pattern: 437   
  15.   
  16. StringTokenzier: 109   
  17. Scanner: 3266   
  18. String: 469   
  19. Pattern: 437   
  20.   
  21. StringTokenzier: 109   
  22. Scanner: 3297   
  23. String: 469   
  24. Pattern: 422   
 StringTokenzier: 110
Scanner: 3281
String: 453
Pattern: 438

StringTokenzier: 109
Scanner: 3297
String: 453
Pattern: 438

StringTokenzier: 110
Scanner: 3265
String: 485
Pattern: 437

StringTokenzier: 109
Scanner: 3266
String: 469
Pattern: 437

StringTokenzier: 109
Scanner: 3297
String: 469
Pattern: 422


StringTokenizer最快
Scanner最慢。
String和Pattern速度差不多。Pattern稍快些。

 

 

 

 

 

 

 

 

 

 

 

 

////////////////////////////////////////////////////////////////

 

 

zhouxiang_fly 写道
额,弱弱的问一下,将Pattern改在外面是如何改的。。。


循环外面。
只用一个Pattern
然后当成参数传进去。这就是dennis_zane大哥说的缓存吧。

Java代码
  1. public   static   void  test4(Pattern pattern){    
  2.     String input = "This is 1 just a test" ;    
  3.     String [] str = pattern.split(input);    
  4.     for ( int  i= 0 ;i
  5.         String s = str[i];    
  6.     }    
  7. }  
  8. public   static   void  main(String [] args){   
  9.     Pattern pattern = Pattern.compile("//s{1}" );  
  10.     start = System.currentTimeMillis();    
  11.     for ( int  i= 0 ;i< 100000 ;i++){    
  12.         test4(pattern);    
  13.     }    
  14.     end = System.currentTimeMillis();    
  15.     System.out.println("Pattern: " +(end-start));   
  16. }  
public static void test4(Pattern pattern){  
    String input = "This is 1 just a test";  
    String [] str = pattern.split(input);  
    for(int i=0;i


明白?

humaeks 写道
我没记错的话ST遇到"|" 作为字段分隔符会死。


刚试了下,确实是这样的。
不知道为什么。有空了看下源代码

你可能感兴趣的:(其它)