一、String的split()方法的使用
Java中对于字符串的截取操作,最常使用的是split()方法,这个方法可以根据给定的正则表达式将字符串切分成多个子串。在对基础类型或简单类型的字符串进行操作时,非常容易上手,只需要简单的几行代码就可以完成。例如,我们可以像下面这样对字符串进行分割:
String str = "apple, banana, orange"; String[] strs = str.split(", "); for (String s : strs) { System.out.println(s); }
上面的代码中,我们定义了一个字符串变量”str”,它包含了三个水果的名称,然后使用split()方法将其切分成三个子串。使用for循环遍历字符串数组,输出每个子串的值。运行以上代码,得到的输出结果为:
apple banana orange
从以上代码中可以看出,使用split()方法的优点在于可以准确地根据指定的分隔符来分割字符串,非常方便。但是,当面对一些比较复杂的字符串匹配场景时,其效率就会出现问题,例如,字符串中包含大量的逗号分隔符,使用split()方法就会导致内存和时间的浪费,这个时候需要采用更为高效的算法。
二、根据模式匹配进行字符串分割
如果我们只需要在字符串中找到第n个逗号,并在其前后分别截取,那么可以采用正则表达式来实现。以下代码演示了如何使用Pattern和Matcher类在字符串中查找第一个逗号,并把它前后的子串输出到控制台。
String str = "Java is cool, isn't it?"; Pattern pattern = Pattern.compile("(.*),(.*)"); Matcher matcher = pattern.matcher(str); if (matcher.find()) { System.out.println("Before comma: " + matcher.group(1)); System.out.println("After comma: " + matcher.group(2)); }
运行以上代码,得到的输出结果为:
Before comma: Java is cool After comma: isn't it?
可以看到,使用正则表达式的方式能够很好地实现字符串的分割,而且具有更高的灵活性。但是,由于Pattern和Matcher类的使用需要较多的代码,其效率相对较低,不适用于高负载场景。
三、自定义算法实现字符串的分割
对于复杂的字符串分割情况,我们还可以采用自定义算法实现。以下代码演示了如何通过遍历字符串的方式查找逗号,并对其前后的子串分别存储在一个字符串数组中:
public static String[] split(String str, char separator) { if (str == null || str.length() == 0) { return new String[0]; } List list = new ArrayList(); int start = 0; for (int i = 0; i < str.length(); i++) { if (str.charAt(i) == separator) { list.add(str.substring(start, i)); start = i + 1; } } list.add(str.substring(start, str.length())); String[] array = new String[list.size()]; return list.toArray(array); }
接下来我们可以测试一下这个方法:
String str = "Microsoft, Windows, OS, Seven"; String[] strs = split(str, ','); for (String s : strs) { System.out.println(s); }
输出结果为:
Microsoft Windows OS Seven
可以看到,该算法实现比正则表达式效率更高,同时还支持自定义分隔符。
四、性能比较
在实际应用中,选择使用哪种分割字符串的方式,一般需要根据具体的场景来决定。下面我们来比较一下不同分割字符串的方式的性能。以下代码演示了如何使用JMH基准测试方法来进行性能比较。
@BenchmarkMode(Mode.AverageTime) @OutputTimeUnit(TimeUnit.NANOSECONDS) @State(Scope.Benchmark) public class MyBenchmark { private static final String STR = "ab,cde,fgh,ijk,lmn,opq,rst,uvw,xyz"; private static final char SEPARATOR = ','; @Benchmark public String[] testSplit() { return STR.split(Character.toString(SEPARATOR)); } @Benchmark public String[] testMatch() { Pattern pattern = Pattern.compile("[^" + SEPARATOR + "]+"); Matcher matcher = pattern.matcher(STR); int count = 0; while (matcher.find()) { count++; } String[] tokens = new String[count]; matcher.reset(); count = 0; while (matcher.find()) { tokens[count++] = matcher.group(); } return tokens; } @Benchmark public String[] testCustom() { List result = new ArrayList(); int start = 0; for (int i = 0; i < STR.length(); i++) { if (STR.charAt(i) == SEPARATOR) { result.add(STR.substring(start, i)); start = i + 1; } } result.add(STR.substring(start)); return result.toArray(new String[0]); } public static void main(String[] args) throws Exception { Options opt = new OptionsBuilder() .include(MyBenchmark.class.getSimpleName()) .forks(1) .build(); new Runner(opt).run(); } }
代码说明:
- 首先使用@BenchmarkMode注解指定运行模式,这里选择的是AverageTime
- 使用@OutputTimeUnit注解指定输出时间的单位,这里选择的是纳秒
- 使用@State注解指定测试用例的作用域,这里选择的是Benchmark
- 然后分别定义testSplit()、testMatch()、testCustom()三个测试方法
- 在这三个方法中,我们分别采用了String的split()方法、Pattern和Matcher类以及自定义的算法来进行字符串分割
- 在main()方法中,我们使用JMH的Runner类来运行基准测试
- 运行以上代码,结果如下表所示:
方法 | 运行时间(ns) |
---|---|
testSplit() | 840 |
testMatch() | 1169 |
testCustom() | 295 |
从结果中可以看出,自定义算法的运行时间最短,性能最优。
五、总结
Java中对于字符串的截取操作,常用的方法是split()、正则表达式和自定义算法。其中,split()方法适用于简单的字符串截取场景,正则表达式具有更高的灵活性,而自定义算法在性能和稳定性上都比较优秀。
原创文章,作者:SHXHV,如若转载,请注明出处:https://www.506064.com/n/372719.html