Kontroller, om en streng indeholder en understreng

1. Oversigt

I denne vejledning gennemgår vi flere måder at kontrollere, om en Snor indeholder en substring, og vi sammenligner ydeevnen for hver.

2. String.indexOf

Lad os først prøve at bruge String.indexOf metode. indeks af giver os den første position, hvor understrenget findes, eller -1, hvis det slet ikke findes.

Når vi søger efter "Rhap", vender den tilbage 9:

Assert.assertEquals (9, "Bohemian Rhapsodyan" .indexOf ("Rhap"));

Når vi søger efter "rhap", det vender tilbage -1, fordi det er store og små bogstaver.

Assert.assertEquals (-1, "Bohemian Rhapsodyan" .indexOf ("rhap")); Assert.assertEquals (9, "Bohemian Rhapsodyan" .toLowerCase (). IndexOf ("rhap"));

Det er også vigtigt at bemærke, at hvis vi søger på underlag “An”, det returnerer 6, fordi det returnerer den første forekomst:

Assert.assertEquals (6, "Bohemian Rhapsodyan" .indexOf ("an"));

3. Streng. Indeholder

Lad os derefter prøve Streng. Indeholder. indeholder vil søge i et underlag gennem hele Snor og vender tilbage rigtigt hvis det findes og falsk Ellers.

I dette eksempel indeholder vender tilbage rigtigt fordi "Hey" findes.

Assert.assertTrue ("Hey Ho, lad os gå". Indeholder ("Hey"));

Hvis strengen ikke findes, indeholder vender tilbage falsk:

Assert.assertFalse ("Hey Ho, lad os gå". Indeholder ("jey"));

I det sidste eksempel findes "hej" ikke fordi Streng. Indeholder er store og små bogstaver

Assert.assertFalse ("Hey Ho, lad os gå". Indeholder ("hej")); Assert.assertTrue ("Hey Ho, lad os gå" .toLowerCase (). Indeholder ("hej"));

Et interessant punkt er det indeholder internt opkald indeks afat vide, om en underlag er indeholdt eller ej.

4. StringUtils.containsIgnoreCase

Vores tredje tilgang vil være at bruge StringUtils #indeholderIgnoreCase fra Apache Commons Lang-biblioteket:

Assert.assertTrue (StringUtils.containsIgnoreCase ("Runaway train", "train")); Assert.assertTrue (StringUtils.containsIgnoreCase ("Runaway train", "Train"));

Vi kan se, at det vil kontrollere, om en underlag er indeholdt i en Snorignorerer sagen. Derfor indeholderIgnoreCase vender tilbage rigtigt når vi søger efter "Trai" og også "trai" inde i "Runaway Train".

Denne tilgang vil ikke være så effektiv som de tidligere tilgange da det tager ekstra tid at ignorere sagen. indeholderIgnoreCase internt konverterer hvert bogstav til store bogstaver og sammenligner de konverterede bogstaver i stedet for de oprindelige.

5. Brug Mønster

Vores sidste tilgang vil være at bruge en Mønster med et regelmæssigt udtryk:

Mønster mønster = Mønster.kompil ("(?

Det kan vi observere vi har brug for at bygge Mønster først, så er vi nødt til at oprette Matcher, og endelig kan vi tjekke med finde metode, hvis der er en forekomst af substring eller ej:

Matcher matcher = pattern.matcher ("Hit the road Jack"); Assert.assertTrue (matcher.find ());

For eksempel første gang det finde udføres, vender det tilbage rigtigt fordi ordet "vej" er indeholdt i strengen "Hit the road Jack", men når vi prøver at finde det samme ord i strengen "og kommer du ikke mere tilbage" vender det tilbage falsk:

Matcher matcher = pattern.matcher ("og kommer du ikke mere tilbage"); Assert.assertFalse (matcher.find ());

6. Ydeevnesammenligning

Vi bruger en open source mikro-benchmark ramme kaldet Java Microbenchmark sele (JMH) for at afgøre, hvilken metode der er mest effektiv med hensyn til udførelsestid.

6.1. Opsætning af benchmark

Som i alle JMH-benchmarks har vi evnen til at skrive en Opsætning metode for at have visse ting på plads, før vores benchmarks køres:

@Setup public void setup () {message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit," + "sed do eiusmod temporid incididunt ut labore et dolore magna aliqua." + "Ud enim ad minim veniam, quis nostrud motion ullamco laboris "+" nisi ut aliquip ex ea commodo consequat. Duis aute irol dolor in "+" reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. "+" Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt "+" mollit anim id est laborum "; mønster = Pattern.compile ("(?

I Opsætning metode initialiserer vi besked Mark. Vi bruger dette som kildetekst til vores forskellige søgeimplementeringer.

Vi initialiserer også mønster for at bruge det senere i en af ​​vores benchmarks.

6.2. Det String.indexOf Benchmark

Vores første benchmark vil bruge indeks af:

@Benchmark public int indexOf () {return message.indexOf ("eiusmod"); }

Vi søger i hvilken position "eiusmod" er til stede i besked variabel.

6.3. Det Streng. Indeholder Benchmark

Vores andet benchmark vil bruge indeholder:

@Benchmark public boolean indeholder () {return message.contains ("eiusmod"); }

Vi prøver at finde ud af, om besked værdi indeholder “Eiusmod”, det samme underlag anvendt i det tidligere benchmark.

6.4. Det StringUtils.containsIgnoreCase Benchmark

Vores tredje benchmark vil bruge StringUtils #indeholderIgnoreCase:

@Benchmark public boolean containStringUtilsIgnoreCase () {return StringUtils.containsIgnoreCase (meddelelse, "eiusmod"); }

Som med de tidligere benchmarks søger vi i underlag i besked værdi.

6.5. Det Mønster Benchmark

Og vores sidste benchmark vil bruge Mønster:

@Benchmark offentlig boolsk searchWithPattern () {return pattern.matcher (meddelelse) .find (); }

Vi bruger det mønster, der er initialiseret i Opsætning metode til at oprette en Matcher og være i stand til at ringe til finde metode ved hjælp af samme understreng som før.

6.6. Analyse af benchmarkresultater

Det er vigtigt at bemærke det vi evaluerer benchmarkresultaterne i nanosekunder.

Efter at have kørt vores JMH-test kan vi se den gennemsnitlige tid, hver tog:

  • indeholder: 14,736 ns
  • indeks af: 14.200 ns
  • indeholderStringUtilsIgnoreCase: 385,632 ns
  • searchWithPattern: 1014,633 ns

indeks af metoden er den mest effektive, tæt fulgt af indeholder. Det giver mening indeholder tog længere tid, fordi det bruger indeks af internt.

indeholderStringUtilsIgnoreCase tog ekstra tid sammenlignet med de foregående, fordi det ikke skelnes mellem store og små bogstaver.

searchWithPattern, tog en endnu højere gennemsnitstid den sidste, bevis for at bruge Mønsters er det værste alternativ til denne opgave.

7. Konklusion

I denne artikel har vi undersøgt forskellige måder at søge efter en substring i en Snor. Vi har også benchmarket præstationen for de forskellige løsninger.

Som altid er koden tilgængelig på GitHub.