龙空技术网

「Java必修课」判断String是否包含子串的四种方法及性能对比

那只斑马还没有睡 44

前言:

现在咱们对“apache stringutils”大约比较珍视,你们都想要剖析一些“apache stringutils”的相关资讯。那么小编也在网摘上收集了一些关于“apache stringutils””的相关资讯,希望大家能喜欢,姐妹们一起来了解一下吧!

1 简介

判断一个字符串是否包含某个特定子串是常见的场景,比如判断一篇文章是否包含敏感词汇、判断日志是否有ERROR信息等。本文将介绍四种方法并进行性能测试。

2 四种方法2.1 JDK原生方法String.indexOf

String的函数中,提供了indexOf(subStr)方法,返回子串subStr第一次出现的位置,如果不存在则返回-1。例子如下:

//包含JavaassertEquals(7, "Pkslow Java".indexOf("Java"));//如果包含多个,返回第一次出现位置assertEquals(0, "Java Java".indexOf("Java"));//大小写敏感assertEquals(-1, "Google Guava".indexOf("guava"));
2.2 JDK原生方法String.contains

最直观判断的方法是contains(subStr),返回类型为boolean,如果包含返回true,不包含则返回false。例子如下:

//包含JavaassertTrue("code in Java".contains("Java"));//大小写敏感,不包含GOassertFalse("Let's go".contains("GO"));//转为大写后包含assertTrue("Let's go".toUpperCase().contains("GO"));

实际上,Stringcontains方法是通过调用indexOf方法来判断的,源码如下:

public boolean contains(CharSequence s) {  return indexOf(s.toString()) > -1;}
2.3 JDK原生正则匹配Pattern

通过强大的正则匹配来判断,虽然有点杀鸡用牛刀的感觉,但也不是不能用,例子如下:

Pattern pattern = Pattern.compile("Java");//包含JavaMatcher matcher1 = pattern.matcher("Python, Java, Go, C++");assertTrue(matcher1.find());//不包含JavaMatcher matcher2 = pattern.matcher("Python, C, Go, Matlab");assertFalse(matcher2.find());
2.4 Apache库StringUtils.contains

Apache的commons-lang3提供许多开箱即用的功能,StringUtils就提供了许多与字符串相关的功能,例子如下:

//包含subassertTrue(StringUtils.contains("String subString", "sub"));//大小写敏感assertFalse(StringUtils.contains("This is Java", "java"));//忽略大小写assertTrue(StringUtils.containsIgnoreCase("This is Java", "java"));
3 性能对比

我们使用JMH工具来对四种方法进行性能测试,Maven引入代码如下:

<dependency>  <groupId>org.openjdk.jmh</groupId>  <artifactId>jmh-core</artifactId>  <version>${openjdk.jmh.version}</version></dependency><dependency>  <groupId>org.openjdk.jmh</groupId>  <artifactId>jmh-generator-annprocess</artifactId>  <version>${openjdk.jmh.version}</version></dependency>

测试代码如下:

@BenchmarkMode(Mode.AverageTime)@OutputTimeUnit(TimeUnit.NANOSECONDS)public class StringContainsPerformanceTest {    @State(Scope.Thread)    public static class MyState {        private String text = "If you want to be smart; read. If you want to be really smart; read a lot.";        Pattern pattern = Pattern.compile("read");    }    @Benchmark    public int indexOf(MyState state) {        return state.text.indexOf("read");    }    @Benchmark    public boolean contains(MyState state) {       return state.text.contains("read");    }    @Benchmark    public boolean stringUtils(MyState state) {        return StringUtils.contains(state.text, "read");    }    @Benchmark    public boolean pattern(MyState state) {        return state.pattern.matcher(state.text).find();    }    public static void main(String[] args) throws Exception {        Options options = new OptionsBuilder()                .include(StringContainsPerformanceTest.class.getSimpleName())                .threads(6)                .forks(1)                .warmupIterations(3)                .measurementIterations(6)                .shouldFailOnError(true)                .shouldDoGC(true)                .build();        new Runner(options).run();    }}

测试结果如下:

Benchmark    Mode  Cnt    Score    Error  Unitscontains     avgt    6   11.331 ±  1.435  ns/opindexOf      avgt    6   11.250 ±  1.822  ns/oppattern      avgt    6  101.196 ± 12.047  ns/opstringUtils  avgt    6   29.046 ±  3.873  ns/op

最快的就是indexOf方法,其次是contains方法,二者应该没有实际区别,contains是调用indexOf来实现的。Apache的StringUtils为第三方库,相对慢一些。最慢的是使用了正则的Pattern的方法,这不难理解,正则引擎的匹配是比较耗性能的。

4 总结

本文介绍了判断一个字符串是否包含某个特定子串的四种方法,并通过性能测试进行了对比。其中性能最好的是String的indexOf方法和contains方法,建议使用contains方法,性能好,跟indexOf相比,更直观,更不容易犯错。毕竟让每个人时刻记住返回-1代表不存在也不是一件容易的事。

但是,使用indexOfcontains方法都需要注意做判空处理,这时StringUtils的优势就体现出来了。

如果本文对你有帮助,别忘记给我个3连 ,点赞,转发,评论,,咱们下期见。

收藏 等于白嫖,点赞才是真情。

原文

标签: #apache stringutils #java判断包含字符串 #java中如何表示字符串 #js 字符串indexof #js 判断字符串是否为数字的函数