Skontrolujte, či reťazec obsahuje podreťazec

1. Prehľad

V tomto návode preskúmame niekoľko spôsobov kontroly, či a String obsahuje podreťazec a porovnáme výkon každého z nich.

2. String.indexOf

Najprv skúsme použiť String.indexOf metóda. indexOf nám dáva prvú pozíciu, kde sa nachádza podreťazec, alebo -1, ak sa nenájde vôbec.

Keď hľadáme výraz „Rhap“, vráti sa 9:

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

Keď hľadáme výraz „rhap“, vráti -1, pretože rozlišuje veľké a malé písmená.

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

Je tiež dôležité poznamenať, že ak hľadáme podreťazec „An“, vráti 6, pretože vráti prvý výskyt:

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

3. Reťazec. Obsahuje

Ďalej to skúsme Reťazec. Obsahuje. obsahuje prehľadá podreťazec v celom rozsahu String a vráti sa pravda ak sa nájde a nepravdivé inak.

V tomto príklade obsahuje vracia pravda pretože sa nachádza „Hej“.

Assert.assertTrue ("Hej Ho, poďme". Obsahuje ("Hej"));

Ak reťazec nenájdete, obsahuje vracia nepravdivé:

Assert.assertFalse ("Hej Ho, poďme" .obsahuje ("jey"));

V poslednom príklade sa výraz „hej“ nenašiel, pretože Reťazec. Obsahuje rozlišuje veľké a malé písmená.

Assert.assertFalse ("Hej Ho, poďme". Obsahuje ("hej")); Assert.assertTrue ("Hej Ho, poďme" .toLowerCase (). Contains ("hej"));

Zaujímavým bodom je to obsahuje interne volá indexOfvedieť, či a podreťazec je obsiahnutá alebo nie.

4. StringUtils.containsIgnoreCase

Náš tretí prístup bude využívať StringUtils #containsIgnoreCase z knižnice Apache Commons Lang:

Assert.assertTrue (StringUtils.containsIgnoreCase („Runaway vlak“, „vlak“))); Assert.assertTrue (StringUtils.containsIgnoreCase ("Runaway vlak", "vlak"));

Môžeme to vidieť skontroluje, či a podreťazec je obsiahnutá v a String, prípad ignoruje. Preto containsIgnoreCase vracia pravda keď hľadáme „Trai“ a „Trai“ vo vnútri „Runaway Train“.

Tento prístup nebude také efektívne ako predchádzajúce prístupy pretože ignorovanie prípadu si vyžaduje ďalší čas. containsIgnoreCase vnútorne prevádza každé písmeno na veľké a porovnáva prevedené písmená namiesto pôvodných.

5. Používanie Vzor

Náš posledný prístup bude používať a Vzor s regulárnym výrazom:

Pattern pattern = Pattern.compile ("(?

Môžeme to pozorovať musíme postaviť Vzor najskôr musíme vytvoriť Matchera nakoniec to môžeme skontrolovať pomocou Nájsť metóda, ak sa vyskytne podreťazec alebo nie:

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

Napríklad prvýkrát Nájsť sa vykoná, vráti sa pravda pretože slovo „cesta“ je obsiahnuté vo vnútri reťazca „Hit the road Jack“, ale keď sa pokúsime nájsť to isté slovo v reťazci „a už sa nevracaj“, vráti sa nepravda:

Matcher matcher = pattern.matcher ("a už sa nevracajte"); Assert.assertFalse (matcher.find ());

6. Porovnanie výkonu

Použijeme open-source mikro-benchmarkový rámec s názvom Java Microbenchmark Harness (JMH) s cieľom rozhodnúť, ktorá metóda je z hľadiska času vykonania najefektívnejšia.

6.1. Benchmark Setup

Ako v každom benchmarku JMH, aj tu máme možnosť napísať a nastaviť aby sme dosiahli určité veci pred spustením našich testovacích kritérií:

@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 exercitation ullamco laboris „+“ nisi ut aliquip ex ea commodosequat. 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 ("(?

V nastaviť metóda, inicializujeme správa lúka. Použijeme to ako zdrojový text pre naše rôzne implementácie vyhľadávania.

Tiež sa inicializujeme vzor aby sme ho mohli neskôr použiť v jednej z našich referenčných hodnôt.

6.2. The String.indexOf Referenčná hodnota

Použije sa náš prvý benchmark indexOf:

@Benchmark public int indexOf () {návrat message.indexOf ("eiusmod"); }

Budeme hľadať v ktorej polohe sa „eiusmod“ nachádza v správa premenná.

6.3. The Reťazec. Obsahuje Referenčná hodnota

Použije sa náš druhý štandard obsahuje:

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

Pokúsime sa zistiť, či správa hodnotu obsahuje „Eiusmod“, to isté podreťazec použité v predchádzajúcej referenčnej hodnote.

6.4. The StringUtils.containsIgnoreCase Referenčná hodnota

Použije sa náš tretí benchmark StringUtils #containsIgnoreCase:

@Benchmark public boolean containsStringUtilsIgnoreCase () {return StringUtils.containsIgnoreCase (správa, "eiusmod"); }

Rovnako ako v predchádzajúcich porovnávacích testoch budeme prehľadávať podreťazec v správa hodnotu.

6.5. The Vzor Referenčná hodnota

A použije sa náš posledný benchmark Vzor:

@Benchmark public boolean searchWithPattern () {návratový vzor.matcher (správa) .find (); }

Použijeme vzor inicializovaný v nastaviť metóda na vytvorenie a Matcher a byť schopný volať Nájsť metódou s použitím rovnakého podreťazca ako predtým.

6.6. Analýza výsledkov referenčných kritérií

Je dôležité si to uvedomiť hodnotíme porovnávacie výsledky v nanosekundách.

Po vykonaní nášho testu JMH môžeme vidieť priemerný čas, ktorý každý z nich trval:

  • obsahuje: 14,736 ns
  • indexOf: 14.200 ns
  • containsStringUtilsIgnoreCase: 385,632 ns
  • searchWithPattern: 1014,633 ns

indexOf najefektívnejšia metóda, za ktorou nasleduje obsahuje. Dáva to zmysel obsahuje trvalo dlhšie, pretože sa používa indexOf vnútorne.

containsStringUtilsIgnoreCase v porovnaní s predchádzajúcimi potreboval viac času, pretože sa v ňom nerozlišujú malé a veľké písmená.

searchWithPattern, trvalo poslednému ešte vyšší priemerný čas, dokazujúci, že pomocou Vzors je najhoršou alternatívou pre túto úlohu.

7. Záver

V tomto článku sme preskúmali rôzne spôsoby hľadania podreťazca v a String. Tiež sme porovnali výkonnosť rôznych riešení.

Ako vždy, kód je k dispozícii na GitHub.