Sjekk om en streng inneholder en streng

1. Oversikt

I denne opplæringen vil vi gjennomgå flere måter å sjekke om en String inneholder en substring, og vi vil sammenligne ytelsen til hver.

2. String.indexOf

La oss først prøve å bruke String.indexOf metode. oversikt over gir oss den første posisjonen der understrengen er funnet, eller -1 hvis den ikke finnes i det hele tatt.

Når vi søker etter “Rhap”, vil den returnere 9:

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

Når vi søker etter "rhap", det returnerer -1 fordi det er skiftesensitivt.

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

Det er også viktig å merke seg at hvis vi søker i underlag “An”, den returnerer 6 fordi den returnerer den første forekomsten:

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

3. String. Inneholder

La oss prøve String. Inneholder. inneholder vil søke i et underlag gjennom hele String og kommer tilbake ekte hvis den er funnet og falsk ellers.

I dette eksemplet, inneholder returnerer ekte fordi “Hei” er funnet.

Assert.assertTrue ("Hei Ho, la oss gå". Inneholder ("Hei"));

Hvis strengen ikke blir funnet, inneholder returnerer falsk:

Assert.assertFalse ("Hei Ho, la oss gå" .contains ("jey"));

I det siste eksemplet blir ikke "hei" funnet fordi String. Inneholder er store og små bokstaver.

Assert.assertFalse ("Hei Ho, la oss gå." Inneholder ("hei")); Assert.assertTrue ("Hei Ho, la oss gå" .toLowerCase (). Inneholder ("hei"));

Et interessant poeng er det inneholder internt samtaler oversikt overå vite om en underlag er inneholdt, eller ikke.

4. StringUtils.containsIgnoreCase

Den tredje tilnærmingen vår vil være å bruke StringUtils #inneholderIgnoreCase 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 sjekke om en underlag er inneholdt i en String, ignorerer saken. Derfor inneholderIgnoreCase returnerer ekte når vi søker etter “Trai” og også “trai” inne i “Runaway Train”.

Denne tilnærmingen vil ikke være så effektiv som den forrige tilnærmingen ettersom det tar ekstra tid å ignorere saken. inneholderIgnoreCase konverterer hver bokstav til store bokstaver internt og sammenligner de konverterte bokstavene i stedet for de opprinnelige.

5. Bruke Mønster

Den siste tilnærmingen vår er å bruke en Mønster med et vanlig uttrykk:

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

Vi kan observere det vi trenger å bygge Mønster først, så må vi lage Matcher, og til slutt kan vi sjekke med finne metode hvis det forekommer substring eller ikke:

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

For eksempel første gang det finne utføres, returnerer den ekte fordi ordet "road" er inne i strengen "Hit the road Jack", men når vi prøver å finne det samme ordet i strengen "og kommer du ikke lenger tilbake", returnerer det falsk:

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

6. Sammenligning av ytelse

Vi bruker et open-source micro-benchmark framework kalt Java Microbenchmark sele (JMH) for å bestemme hvilken metode som er mest effektiv når det gjelder utførelsestid.

6.1. Referanseoppsett

Som i alle JMH-referanser har vi muligheten til å skrive en oppsett metoden, for å ha visse ting på plass før våre referanseverdier kjø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." + "Ut enim ad minim veniam, quis nostrud training ullamco laboris "+" nisi ut aliquip ex ea commodo consequat. Duis aute irure 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 = Mønster.kompilere ("(?

I oppsett metoden initialiserer vi beskjed felt. Vi bruker dette som kildetekst for de forskjellige søkeimplementeringene våre.

Vi initialiserer også mønster for å bruke den senere i en av våre referanser.

6.2. De String.indexOf Referanseindeks

Vår første målestokk vil bruke oversikt over:

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

Vi søker i hvilken posisjon "eiusmod" er tilstede i beskjed variabel.

6.3. De String. Inneholder Referanseindeks

Vår andre målestokk vil bruke inneholder:

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

Vi prøver å finne ut om beskjed verdi inneholder “Eiusmod”, det samme underlag brukt i forrige referanseindeks.

6.4. De StringUtils.containsIgnoreCase Referanseindeks

Vår tredje målestokk vil bruke StringUtils #inneholderIgnoreCase:

@Benchmark offentlig boolsk inneholderStringUtilsIgnoreCase () {return StringUtils.containsIgnoreCase (melding, "eiusmod"); }

Som med de tidligere referansene, søker vi i underlag i beskjed verdi.

6.5. De Mønster Referanseindeks

Og vår siste målestokk vil bruke Mønster:

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

Vi bruker mønsteret initialisert i oppsett metode for å lage en Matcher og kunne ringe finne metode, ved å bruke samme underlag som før.

6.6. Analyse av referanseresultater

Det er viktig å merke seg det vi evaluerer referanseresultatene i nanosekunder.

Etter å ha kjørt JMH-testen vår, kan vi se gjennomsnittlig tid hver tok:

  • inneholder: 14,736 ns
  • oversikt over: 14.200 ns
  • inneholderStringUtilsIgnoreCase: 385.632 ns
  • searchWithPattern: 1014.633 ns

oversikt over metoden er den mest effektive, tett fulgt av inneholder. Det er fornuftig det inneholder tok lengre tid fordi bruker oversikt over internt.

inneholderStringUtilsIgnoreCase tok ekstra tid sammenlignet med de forrige fordi det ikke skiller mellom store og små bokstaver.

searchWithPattern, tok en enda høyere gjennomsnittstid den siste, beviser at bruk Mønsters er det verste alternativet for denne oppgaven.

7. Konklusjon

I denne artikkelen har vi utforsket ulike måter å søke etter en understreng i String. Vi har også benchmarket ytelsen til de forskjellige løsningene.

Som alltid er koden tilgjengelig på GitHub.