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.