0.如何计算一个字符在字符串中出现的次数?|Java Debug 笔记

496 阅读1分钟

本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看<活动链接>

问题

我有一个字符串

"a.b.c.d"

我想用一种简单明了的方法统计字符'.'出现的次数,最好一行代码搞定。
限制条件:不使用循环

热门答案


答案1:

我的一行代码方案:

int count = StringUtils.countMatches("a.b.c.d", ".");

为什么要自己实现commons lang已有的功能呢?
Spring Framework也有相似的功能:

int occurance = StringUtils.countOccurrencesOf("a.b.c.d", ".");

答案2:

int count = line.length() - line.replace(".", "").length();

这样怎么样,没有使用循环。应该比其他使用正则表达式的方法快。

答案3:

总结下其他答案和我所知道的满足一行代码条件的答案。

 String testString = "a.b.c.d";
  • 1.采用Apache Commons的实现
int apache = StringUtils.countMatches(testString, ".");
System.out.println("apache = " + apache);
  • 2.采用Spring Framework的实现
int spring = org.springframework.util.StringUtils.countOccurrencesOf(testString, ".");
System.out.println("spring = " + spring);
  • 3.采用 replace方法的实现
int replace = testString.length() - testString.replace(".", "").length();
System.out.println("replace = " + replace);
  • 4.采用replaceAll方法的实现1
int replaceAll = testString.replaceAll("[^.]", "").length();
System.out.println("replaceAll = " + replaceAll);
  • 5.采用replaceAll方法的实现2
int replaceAllCase2 = testString.length() - testString.replaceAll("\\.", "").length();
System.out.println("replaceAll (second case) = " + replaceAllCase2);
  • 6.采用split方法的实现
int split = testString.split("\\.",-1).length-1;
System.out.println("split = " + split);
  • 7.采用java8语法的实现1
long java8 = testString.chars().filter(ch -> ch =='.').count();
System.out.println("java8 = " + java8);
  • 8.采用java8语法的实现2,对于unicode来说这种方式比7好
long java8Case2 = testString.codePoints().filter(ch -> ch =='.').count();
System.out.println("java8 (second case) = " + java8Case2);
  • 9.采用StringTokenizer的实现
int stringTokenizer = new StringTokenizer(" " +testString + " ", ".").countTokens()-1;
System.out.println("stringTokenizer = " + stringTokenizer);

注意方式9只能对"a.b.c.d"生效,对"a...b.c....d"、"...a.b.c.d"或"a....b......c.....d..."这类就不起作用了。
性能测试(使用JMH,mode = AverageTime,score 0.010优于0.351)

Benchmark              Mode  Cnt  Score    Error  Units
1. countMatches        avgt    5  0.010 ±  0.001  us/op
2. countOccurrencesOf  avgt    5  0.010 ±  0.001  us/op
3. stringTokenizer     avgt    5  0.028 ±  0.002  us/op
4. java8_1             avgt    5  0.077 ±  0.005  us/op
5. java8_2             avgt    5  0.078 ±  0.003  us/op
6. split               avgt    5  0.137 ±  0.009  us/op
7. replaceAll_2        avgt    5  0.302 ±  0.047  us/op
8. replace             avgt    5  0.303 ±  0.034  us/op
9. replaceAll_1        avgt    5  0.351 ±  0.045  us/op

文章翻译自Stack Overflow