Controleer of een string een substring bevat

1. Overzicht

In deze zelfstudie bespreken we verschillende manieren om te controleren of een Draad bevat een substring, en we zullen de prestaties van elk vergelijken.

2. String.indexOf

Laten we eerst proberen de String.indexOf methode. index van geeft ons de eerste positie waar de subtekenreeks wordt gevonden, of -1 als deze helemaal niet wordt gevonden.

Wanneer we zoeken naar "Rhap", wordt 9 geretourneerd:

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

Als we zoeken naar "rhap", het retourneert -1 omdat het hoofdlettergevoelig is.

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

Het is ook belangrijk op te merken dat als we zoeken in het deelstring "An", het retourneert 6 omdat het het eerste exemplaar retourneert:

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

3. String. Bevat

Laten we het vervolgens proberen String. Bevat. bevat zoekt een subtekenreeks door de hele Draad en zal terugkeren waar als het is gevonden en false anders.

In dit voorbeeld bevat geeft terug waar omdat "Hey" is gevonden.

Assert.assertTrue ("Hey Ho, laten we gaan" .contains ("Hey"));

Als de string niet wordt gevonden, bevat geeft terug false:

Assert.assertFalse ("Hey Ho, laten we gaan" .contains ("jey"));

In het laatste voorbeeld wordt "he" niet gevonden omdat String. Bevat is hoofdlettergevoelig.

Assert.assertFalse ("Hey Ho, laten we gaan" .contains ("hey")); Assert.assertTrue ("Hey Ho, laten we gaan" .toLowerCase (). Bevat ("hey"));

Een interessant punt is dat bevat intern oproepen index vanom te weten of a deelstring is ingesloten of niet.

4. StringUtils.containsIgnoreCase

Onze derde benadering zal gebruiken StringUtils #bevatIgnoreCase uit de Apache Commons Lang-bibliotheek:

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

We kunnen zien dat het zal controleren of a deelstring is opgenomen in een Draad, de zaak negerend. Daarom bevatIgnoreCase geeft terug waar wanneer we zoeken naar "Trai" en ook "trai" in "Runaway Train".

Deze aanpak zal niet zo efficiënt zijn als de vorige benaderingen aangezien het extra tijd kost om de zaak te negeren. bevatIgnoreCase converteert intern elke letter naar hoofdletters en vergelijkt de geconverteerde letters in plaats van de originele letters.

5. Met behulp van Patroon

Onze laatste benadering zal een Patroon met een reguliere expressie:

Patroonpatroon = Pattern.compile ("(?

Dat kunnen we waarnemen we moeten het Patroon eerst, dan moeten we het Matcher, en tot slot kunnen we contact opnemen met de vind methode als de subtekenreeks voorkomt of niet:

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

Bijvoorbeeld de eerste keer dat vind wordt uitgevoerd, keert het terug waar omdat het woord 'weg' in de tekenreeks 'Hit the road Jack' staat, maar als we proberen hetzelfde woord te vinden in de tekenreeks 'en kom je niet meer terug', komt het terug vals:

Matcher matcher = pattern.matcher ("en kom niet meer terug"); Assert.assertFalse (matcher.find ());

6. Prestatievergelijking

We zullen een open-source micro-benchmark-framework gebruiken met de naam Java Microbenchmark-harnas (JMH) om te beslissen welke methode het meest efficiënt is in termen van uitvoeringstijd.

6.1. Benchmark-instellingen

Zoals in elke JMH-benchmark, hebben we de mogelijkheid om een opstelling methode, om bepaalde dingen op hun plaats te hebben voordat onze benchmarks worden uitgevoerd:

@Setup public void setup () {message = "Lorem ipsum dolor sit amet, consectetur adipiscing elit," + "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." + "Ut enim ad minim veniam, quis nostrud exercise 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 "; pattern = Pattern.compile ("(?

In de opstelling methode initialiseren we de bericht veld. We gebruiken dit als de brontekst voor onze verschillende zoekimplementaties.

We zijn ook aan het initialiseren patroon om het later in een van onze benchmarks te gebruiken.

6.2. De String.indexOf Benchmark

Onze eerste benchmark zal gebruiken index van:

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

We zoeken in welke positie "eiusmod" aanwezig is in de bericht variabele.

6.3. De String. Bevat Benchmark

Onze tweede benchmark zal gebruiken bevat:

@Benchmark openbare boolean bevat () {retourbericht.contains ("eiusmod"); }

We zullen proberen te achterhalen of het bericht waarde bevat "Eiusmod", hetzelfde deelstring gebruikt in de vorige benchmark.

6.4. De StringUtils.containsIgnoreCase Benchmark

Onze derde benchmark zal gebruiken StringUtils #bevatIgnoreCase:

@Benchmark openbare boolean containsStringUtilsIgnoreCase () {return StringUtils.containsIgnoreCase (bericht, "eiusmod"); }

Net als bij de vorige benchmarks, zullen we zoeken in het deelstring in de bericht waarde.

6.5. De Patroon Benchmark

En onze laatste benchmark zal gebruiken Patroon:

@Benchmark openbare boolean searchWithPattern () {retourpatroon.matcher (bericht) .find (); }

We gebruiken het patroon dat is geïnitialiseerd in het opstelling methode om een Matcher en de vind methode, met dezelfde subtekenreeks als hiervoor.

6.6. Analyse van benchmarkresultaten

Het is belangrijk om dat op te merken we evalueren de benchmarkresultaten in nanoseconden.

Nadat we onze JMH-test hebben uitgevoerd, kunnen we de gemiddelde tijd zien die elk duurde:

  • bevat: 14.736 ns
  • index van: 14.200 ns
  • bevatStringUtilsIgnoreCase: 385.632 ns
  • searchWithPattern: 1014.633 ns

index van methode is de meest efficiënte, op de voet gevolgd door bevat. Het is logisch dat bevat duurde langer omdat wordt gebruikt index van intern.

bevatStringUtilsIgnoreCase kostte extra tijd in vergelijking met de vorige omdat het niet hoofdlettergevoelig is.

searchWithPattern, nam de laatste tijd een nog hogere gemiddelde tijd in beslag, bewijzen dat het gebruiken van Patroons is het slechtste alternatief voor deze taak.

7. Conclusie

In dit artikel hebben we verschillende manieren onderzocht om naar een subtekenreeks in een Draad. We hebben ook de prestaties van de verschillende oplossingen vergeleken.

Zoals altijd is de code beschikbaar op GitHub.


$config[zx-auto] not found$config[zx-overlay] not found