`
floating
  • 浏览: 80809 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

字符串切分工具比较

阅读更多
在日常开发中,我们经常需要处理字符串。字符串处理通常有两个主要的场景:一个是字符串的格式化,通常我们通过String.format方法或者构建一个StringBuilder,然后通过append方法来完成;另一个是字符串的切分。在这篇文章中,通过String.split、Apache Commons中的StringUtils.split和Google工具包Gauva中提供的Splitter三个字符串切分工具的测试来体会一下三者在使用方法和性能上的差异。

在进行实际讨论之前,我们先花一些小的篇幅介绍一下Google的Gauva工具包。实际上,Guava几乎可以看成是一个全新的用更“时髦”(更符合现代编程理念)的Apache Commons的替代品。最新的Guava版本提供了集合、并发、基本类型操作、反射、比较、I/O、哈希、网络通讯、字符串处理、数学处理、基于内存的缓存、基于内存的发布/订阅等等一个庞大而全面的数据访问和处理工具库。

好了,下面就让我们看看在字符串切分上不同的工具会给我们带来什么样的惊喜吧。

我们知道,String类本身实际上已经提供了一个split的方法用来实现字符串的切分。比如,如果我们想把字符串“I am from Newtouch”分成I,am,from,Newtouch四个独立的字符串时,通过以下代码就可以简单的实现。
  final String message = "I am from Newtouch";
	String[] items = message.split(" ");

如果仔细观察,我们会发现,在按空格切分字符串时,虽然空格(‘ ’)只是一个字符,但是仍需要传入一个字符串作为切分匹配的参数。其实,split方法的参数不仅仅只是一个简单的字符串,而且还支持正则表达式的所有语义。仍然以上例为例,如果在两个单词之间(如:I和am)存在两个或者三个以上的空格,我们仍然希望切分结果是I,am,from,Newtouch四个独立的字符串的话,只需按照正则表达式的语法稍微修改一下split的参数。代码如下:
  final String message = "I     am     from              Newtouch";
	String[] items = message.split(" +");

通过这个简单的小例子,我们可以体会到正则表达式的威力。但是,在一些对性能要求非常高的场合,当只需要按照单个字符进行切分时,JDK这种支持正则表达式的切分方法无疑又会成为一种“鸡肋”;而另一种情况则正好相反,对于复杂的切分方式,开发人员很多时候更希望采用一种比正则表达式更好用、也更直白、更易于理解和掌握的方式来书写代码。还好,很多工具包都提供了基单个字符的切分方法,如本文重点讨论的Apache Commons中的StringUtils和Google的Guava工具包提供的Splitter。StringUtils和Splitter使用起来都非常简单。如下所示:
  
  //Apache commons-lang StringUtils.split
	final String message = "I am from Newtouch";
	String[] items = StringUtils.split(message,' ');
  


  //Google Guava Splitter
	final String message = "I am from Newtouch";
  Iterator<String> items = Splitter.on(' ').split(message).iterator();
  
那么,我们在处理一个字符串切分问题时,究竟选择哪种切分工具更好呢?要了解这个问题,我们先看看下面这个性能测试。
public class StringSplitPerformanceTest
{
	//测试循环次数
    static int testDataCount = 5000;
    //测试字符串的长度
    static int testDataStringSize = 100;
    //测试数据集
    static List<String> testData = new LinkedList<String>();
    //测试结果记录
    static StopWatch stopWatch = new StopWatch(String.format("Test the performance of splitting a string which size is %d, %d times.",testDataStringSize,testDataCount));
    
    //创建测试数据
    @BeforeClass
    public static void generateTestData() {
        for(int i=0; i < testDataCount; i++){
            String data = RandomStringUtils
              .random(testDataStringSize, "ABCDEFGHIJKLMNOPQRSTUVXYZ,");
            testData.add(data);
        }
    }

    //输出测试结果
    @AfterClass
    public static void printTestSummery(){
        System.out.println(stopWatch.prettyPrint());
    }

    //测试Apache commons-lang的StringUtils.split
    @Test
    public void apacheCommonLangSplit()  throws Exception {
        stopWatch.start("Apache Common Lang Split");
        for(String data: testData){
            String[] elements = StringUtils.split(data, ',');
            for (String element : elements) {
                assertTrue(element.length() <= testDataStringSize);
            }
        }
        stopWatch.stop();
    }
    
    //测试Goolge Guava的Splitter
    @Test
    public void guavaSplitterSplit() throws Exception {
        Splitter spiltter = Splitter.on(',');
        stopWatch.start("Google Guava Splitter");
        for(String data: testData){
            Iterable<String> elements = spiltter.split(data);
            for (String element : elements) {
                assertTrue(element.length() <= testDataStringSize);
            }
        }
        stopWatch.stop();
    }
    
    //测试String自身的split方法
    @Test
    public void jdkStringSplit() throws Exception {
        stopWatch.start("JDK String Split");
        for(String data: testData){
        	 String[] elements = data.split(",");
            for (String element : elements) {
                assertTrue(element.length() <= testDataStringSize);
            }
        }
        stopWatch.stop();
    }
}

在这个单元测试中,分别使用String.split、Apache commons-lang中的StringUtils.split和Google Guava的Splitter类对随机产生的长度为100的字符串进行5000次切分,并使用了Spring的StopWatch来收集和统计测试结果。三次测试结果如下:

第一次:
StopWatch 'Test the performance of splitting a string which size is 100, 5000 times.': running time (millis) = 239
-----------------------------------------
ms     %     Task name
-----------------------------------------
00037  015%  Apache Common Lang Split
00042  018%  Google Guava Splitter
00160  067%  JDK String Split

第二次:
StopWatch 'Test the performance of splitting a string which size is 100, 5000 times.': running time (millis) = 394
-----------------------------------------
ms     %     Task name
-----------------------------------------
00053  013%  Apache Common Lang Split
00094  024%  Google Guava Splitter
00247  063%  JDK String Split

第三次:
StopWatch 'Test the performance of splitting a string which size is 100, 5000 times.': running time (millis) = 317
-----------------------------------------
ms     %     Task name
-----------------------------------------
00039  012%  Apache Common Lang Split
00045  014%  Google Guava Splitter
00233  074%  JDK String Split

从测试结果中我们发现,JDK自身的split方法性能上远不如其他两个工具;而在需要进行切分的字符串长度比较短(如本测试中的字符串长度为100)的情况下,Apache commons-lang的StringUtils.split的切分效率最高;Google Guava的Splitter在性能上和StringUtils有1倍左右的差距。

本文的最后,我们再讨论一下Splitter的适用场景。有时,我们需要切分的字符串往往不是特别规整。比如我们希望把字符串“I am    from   Newtouch.”切分为“I”,“am”,“from”,“Newtouch”四个单元时,使用正则表达式对开发人员来说就是一个不小的挑战,而且通过上面的测试我们知道正则表达式的处理效率来说并不是很好。使用Splitter可以很灵活的处理了这些问题。
  @Test
	public void testGoogleGuavaSplitter() {
		//Google Guava Splitter
		final String message = "I am   from     Newtouch.";
		Iterator<String> items = Splitter.on(' ') 	//按空格切分
				.trimResults(CharMatcher.is('.'))		//去掉结尾的.
				.omitEmptyStrings()						//去掉多余的空字符串
				.split(message).iterator();
		
		assertEquals("I", items.next());
		assertEquals("am", items.next());
		assertEquals("from", items.next());
		assertEquals("Newtouch", items.next());
	}
6
5
分享到:
评论
3 楼 oaklet 2012-10-30  
java本身对字符串处理支持是弱不少,像commons那一套基础的东东本来应该在jdk里啊
如果不是项目必须的话,还是用脚本操作字符更便捷一些
2 楼 obullxl 2012-10-30  
一直在用apache-commons的工具包,Guava这个试试。
1 楼 dj4307665 2012-10-28  
一般就用jdk自带的

相关推荐

    纯C++ 字符串处理函数大全源码

    在C++中,标准库没有提供直接的字符串切分功能,因此开发者经常需要自己实现。`Split`函数可能接收一个字符串和一个分隔符作为参数,返回一个字符串向量,其中每个元素都是原字符串中由分隔符分隔的部分。这样的功能...

    C++字符串分割函数+VC助手

    C++字符串分割源码,破解版VC助手,兼容多个windows版本

    易语言分割字符串进制转换工具源码

    这个命令会按照分隔符将字符串切分,并将结果保存到数组中。这对于处理文本数据,如日志文件、CSV格式的数据,或者解析用户输入等场景非常有用。 2. **进制转换**: 进制转换是编程中常见的数据处理任务,包括十...

    学学Python_字符串04_字符串方法02

    它通过指定的分隔符来切分字符串。例如,如果你有一个字符串`"Hello, World! How are you?"`,你可以用空格作为分隔符,调用 `split()` 方法将其分割为单词列表: ```python s = "Hello, World! How are you?" ...

    精彩编程与编程技巧-切分字符串...

    在编程中,字符串切分是一种常见的操作,用于将一个较长的字符串按照一定的规则(如指定的分隔符)分割成多个较小的部分。这种操作广泛应用于数据处理、文本分析等领域。 #### 实现方法: 在多种编程语言中,都有...

    数据库字符串处理 很不错

    ### 数据库字符串处理知识点 ...案例中的 `dbo.Split` 函数为我们提供了一个实用的字符串分割工具,可以帮助我们在实际工作中更高效地处理字符串相关的任务。希望读者能够掌握这些技巧,并将其应用到自己的项目中去。

    使用strtok函数截取字符串得到相应的子串存入数组中

    在C/C++编程中,`strtok`函数是一种常用的字符串处理工具,用于将字符串分割成多个子串。这个函数在处理复杂格式的数据时非常有用,比如解析包含多种数据类型的字符串。在给定的场景中,我们需要从一个字符串中提取...

    c#中根据标点符号对字符串进行分行

    而VS(Visual Studio)作为C#的主要开发环境,提供了丰富的调试和测试工具,可以帮助开发者更好地编写、测试和优化这种字符串处理代码。 在压缩包中的文件"039"可能是源代码示例或者更详细的教程,如果你有这个文件...

    python核心数据类型-字符串demo

    在Python中,字符串可以与其他数据类型进行比较,比如比较它们的字母顺序。此外,字符串也支持模式匹配,例如通过正则表达式库`re`进行复杂搜索和替换操作。 字符串在实际编程中广泛应用,如读写文件、处理用户输入...

    10 深入学习字符串.zip

    7. **字符串比较**:理解字符串比较的规则,比如在Python中,字符串是按照字典顺序比较的,而不仅仅是基于字符的ASCII值。 8. **字符串处理算法**:如KMP算法、Rabin-Karp算法等,用于高效地查找和匹配字符串,这些...

    JS字符串的切分用法实例

    总结一下,`split()`函数是JavaScript中处理字符串的重要工具,它可以方便地将字符串按照指定的分隔符进行切割,生成新的子字符串数组。结合循环和其他字符串方法,我们可以高效地处理和操作字符串。在实际开发中,`...

    ASP字符串函数大全[文].pdf

    `count`参数可以限制返回的子字符串数量,`start`指定从哪个字符开始切分。 9. `Replace` 函数:在`expression`字符串中,将所有或指定次数的`find`子字符串替换为`replacewith`。`compare`参数和`count`参数与之前...

    分享Python切分字符串的一个不错方法

    本文将详细介绍一种基于Python标准库中的`re`模块进行字符串切分的方法,并与传统的方法进行对比,以便读者能够更全面地理解并灵活运用这些技巧。 #### 传统方法:使用切片操作 传统的切分字符串方法主要依赖于...

    JS中split()用法(将字符串按指定符号分割成数组)

    `split()`方法是JavaScript字符串处理的重要工具,它能够帮助开发者有效地处理字符串数据,将其转换为可操作的数组形式。通过灵活地设置分隔符和限制返回的数组长度,我们可以适应各种不同的字符串处理需求。 总之...

    PHP explode()函数用法、切分字符串

    `PHP`的`explode()`...总结,`PHP explode()`函数是处理字符串时不可或缺的工具,它能帮助我们轻松地将字符串切割为数组,以便进行更复杂的字符串处理任务。了解并熟练掌握它的用法,能够极大地提高我们的编程效率。

    实现字符串的数据提取,根据一串字符显示的内容,提取对应的数据的实现,此代码实现希望能帮到各位

    在Python中,我们可以使用内置的`str`类提供的方法,如`split()`来按指定分隔符切分字符串,`find()`或`index()`来查找子串,`replace()`来替换特定部分。 在提取数据后,我们需要将其显示在编辑框中。这通常涉及...

    字符拆分程序

    在VB(Visual Basic)编程语言中,字符拆分或字符串分割是一个常见的操作,它涉及到将一个长字符串按照特定的分隔符切分为多个子字符串。这个"字符拆分程序"的功能就是实现这样的操作,比如输入字符串 "ab;cc;dd;ee...

    php 将字符串按大写字母分隔成字符串数组

    因此,当我们使用preg_split()函数并配以该正则表达式作为分割依据时,就能够把字符串在每个大写字母之前的位置切分开来。 例如,在提供的代码中,有两个不同的字符串:"abcDefGhi"和"createTechBook"。使用相同的...

    文件切分合并工具(C#)

    此工具可能使用了DirectoryInfo和FileInfo类来遍历指定目录下的所有文件,并通过字符串操作方法如Replace()来实现文件名的替换。同时,为了避免重名冲突,它可能还会检查新文件名是否存在,如果存在则自动添加序列号...

    PHPAnalysis:一款纯PHP实现的中文切分工具

    因此对于比较短的字符串分词,只需要占极小的资源,比那种一次性载入所有词条的实际性要高得多,并且词库容量大小不会影响分词执行的速度。 PHPAnalysis分词系统是基于字符串匹配的分词方法进行分词的,这种方法又...

Global site tag (gtag.js) - Google Analytics