Meistern von contains() in Java: Wie man effiziente Teilstring‑Suchen durchführt

目次

1. Einführung: Warum die String‑Suche in Java wichtig ist

String‑Manipulation ist einer der am häufigsten genutzten Vorgänge beim Programmieren in Java.
Ob beim Prüfen von Benutzereingaben, beim Parsen von Dateiinhalten oder beim Suchen nach bestimmten Schlüsselwörtern – häufig muss festgestellt werden, ob ein bestimmtes Wort in einem gegebenen String enthalten ist.

Um diesen Bedarf zu decken, stellt Java die praktische Methode contains() bereit.
Mit dieser Methode lässt sich leicht bestimmen, ob ein String teilweise einen anderen enthält.

Beispielsweise kann man mit contains() prüfen, ob eine Fehlermeldung ein bestimmtes Schlüsselwort enthält – und das in einer einzigen Codezeile.

Besonders in Szenarien mit großen Textmengen – etwa Web‑Anwendungen, API‑Verarbeitung oder Log‑Analyse – verbessert die contains()‑Methode die Lesbarkeit und Wartbarkeit des Codes erheblich.

Allerdings gibt es auch wichtige Aspekte wie die Groß‑/Kleinschreibung und die Möglichkeit eines null‑Werts. Dieser Artikel erklärt die Java‑Methode contains() im Detail – von der Grundbenutzung über häufige Fehler bis hin zu Unterschieden zu anderen Methoden und praktischen Anwendungsbeispielen.

Unser Ziel ist es, nützliche Informationen sowohl für Einsteiger als auch für Entwickler zu liefern, die Java in realen Projekten einsetzen.

2. Grundsyntax und Eigenschaften der contains()‑Methode

Die Java‑Methode contains() ermittelt, ob ein String teilweise einen anderen String enthält.
Ihre Syntax ist sehr einfach, sie ist jedoch äußerst praktisch und wird im Alltag häufig verwendet.

Grundsyntax

boolean result = targetString.contains(searchString);

Die Methode gehört zur Klasse String und akzeptiert ein CharSequence (üblicherweise ein String) als Argument.
Ihr Rückgabewert ist boolean: true, wenn der Ziel‑String die angegebene Teilzeichenkette enthält, und false sonst.

Beispielcode

String message = "Java programming is fun!";
boolean hasKeyword = message.contains("programming");

System.out.println(hasKeyword); // Output: true

Im obigen Beispiel ist die Teilzeichenkette "programming" im Ziel‑String enthalten, sodass contains() true zurückgibt.

Eigenschaften der Methode

  • Prüft nur Teilübereinstimmungen: Wenn eine exakte Übereinstimmung nötig ist, verwenden Sie stattdessen equals().
  • Groß‑/Kleinschreibung beachten: Beispielsweise werden "Java" und "java" als unterschiedlich behandelt (Details weiter unten).
  • Unterstützt keine regulären Ausdrücke: Da sie lediglich das Vorhandensein einer Zeichenkette prüft, erfordert das Muster‑Matching matches() oder die Klasse Pattern.

Verhalten bei Übergabe von null

Wird null an contains() übergeben, löst dies eine NullPointerException aus.
Beispiel:

String text = null;
System.out.println(text.contains("test")); // Exception occurs

Ebenso wird dieselbe Ausnahme geworfen, wenn der Ziel‑String selbst null ist.
Daher wird dringend empfohlen, Null‑Prüfungen durchzuführen, bevor contains() aufgerufen wird.

3. Praktische Anwendungsbeispiele und wichtige Überlegungen

Die contains()‑Methode von Java ist sehr intuitiv und praktisch, doch falscher Einsatz kann zu unerwarteten Bugs oder ineffizientem Code führen.
Dieser Abschnitt erklärt die Grundbenutzung von contains() sowie zentrale Punkte, die Sie beachten sollten.

3‑1. Einfaches Anwendungsbeispiel

Der folgende Code demonstriert ein einfaches Beispiel, bei dem geprüft wird, ob der Ziel‑String ein bestimmtes Schlüsselwort enthält:

String sentence = "今日はJavaの勉強をしています。";

if (sentence.contains("Java")) {
    System.out.println("Javaが含まれています。");
} else {
    System.out.println("Javaは含まれていません。");
}

Wie zu sehen, wird contains() häufig mit if‑Anweisungen kombiniert, um bedingte Verzweigungen zu steuern.

3‑2. Groß‑/Kleinschreibung

Die contains()‑Methode ist case‑sensitive.
Beispielsweise liefert der folgende Code false:

String text = "Welcome to Java";
System.out.println(text.contains("java")); // false

In solchen Fällen ist es üblich, die Strings vor dem Vergleich in Klein‑ (oder Groß‑)buchstaben zu konvertieren:

String text = "Welcome to Java";
System.out.println(text.toLowerCase().contains("java")); // true

Dieser Ansatz hilft, Unterschiede in der Eingabeschreibweise zu beseitigen (z. B. Benutzereingaben).

3-3. Umgang mit null und leeren Zeichenketten

Eine der wichtigsten Überlegungen bei der Verwendung von contains() ist der Umgang mit null.
Wenn entweder die Zielzeichenkette oder das Argument null ist, tritt eine NullPointerException auf.

String text = null;
System.out.println(text.contains("test")); // Runtime error

Um dieses Problem zu vermeiden, fügen Sie immer eine Nullprüfung hinzu:

if (text != null && text.contains("test")) {
    // Safe to process
}

Beachten Sie außerdem:
Das Übergeben einer leeren Zeichenkette ("") liefert immer true.

String sample = "test";
System.out.println(sample.contains("")); // true

Dieses Verhalten ist jedoch in der Praxis selten nützlich und kann unbeabsichtigt zu Fehlern führen, wenn leere Zeichenketten versehentlich übergeben werden.

3-4. Unterstützt keine Suche nach mehreren Schlüsselwörtern

contains() kann jeweils nur ein Schlüsselwort prüfen.
Um mehrere Schlüsselwörter zu prüfen, müssen Sie entweder contains() mehrmals aufrufen oder die Stream-API verwenden.

String target = "エラーコード123:アクセス拒否";
if (target.contains("エラー") || target.contains("拒否")) {
    System.out.println("問題のあるメッセージです。");
}

Oder, für dynamische Schlüsselwortmengen:

List<String> keywords = Arrays.asList("エラー", "障害", "失敗");
boolean found = keywords.stream().anyMatch(target::contains);

4. Methoden, die häufig mit contains() verglichen werden

Java bietet mehrere Methoden zum Vergleichen von Zeichenketten oder zum Prüfen, ob ein bestimmter Teilstring existiert.
Unter ihnen wird contains() für „Teilübereinstimmungen“ verwendet, aber andere Methoden dienen ebenfalls ähnlichen Zwecken.
Dieser Abschnitt erklärt die Eigenschaften und Unterschiede dieser Methoden, um Ihnen die korrekte Anwendung zu erleichtern.

4-1. Unterschied zu equals(): Exakte Übereinstimmung vs. Teilübereinstimmung

equals() bestimmt, ob zwei Zeichenketten exakt identisch sind.
Im Gegensatz dazu prüft contains() Teilübereinstimmungen.

String a = "Java";
String b = "Java";

System.out.println(a.equals(b));      // true: Exact match
System.out.println(a.contains("av")); // true: Partial match

Hauptunterschiede:

Comparisonequals()contains()
Match TypeExact matchPartial match
Case SensitivitySensitiveSensitive
Argument TypeObjectCharSequence

Verwendungshinweis:
Verwenden Sie equals(), wenn Werte exakt übereinstimmen müssen (z. B. ID‑Verifizierung).
Verwenden Sie contains(), wenn Teilübereinstimmungen akzeptabel sind (z. B. Stichwortsuche).

4-2. Unterschied zu indexOf(): Ob Sie die Position benötigen

Die Methode indexOf() kann ebenfalls verwendet werden, um zu prüfen, ob ein Teilstring in einer Zeichenkette vorkommt.
Der Unterschied besteht darin, dass indexOf() den Startindex des Teilstrings zurückgibt, falls er gefunden wird.
Wird der Teilstring nicht gefunden, gibt sie -1 zurück.

String text = "Hello, Java World!";
System.out.println(text.indexOf("Java"));    // 7
System.out.println(text.indexOf("Python"));  // -1

Sie können indexOf() auch verwenden, um das Verhalten von contains() nachzuahmen:

if (text.indexOf("Java") >= 0) {
    System.out.println("It is contained.");
}

Verwendungshinweis:
Wenn Sie den Index nicht benötigen, ist contains() lesbarer und vorzuziehen.

4-3. Unterschied zu matches(): Unterstützung von regulären Ausdrücken

Die Methode matches() prüft, ob eine Zeichenkette vollständig einem angegebenen regulären Ausdruck entspricht.
Im Gegensatz dazu prüft contains() nur auf wörtliche Teilstring‑Übereinstimmungen und unterstützt keine regulären Ausdrücke.

String text = "abc123";
System.out.println(text.matches(".*123")); // true
System.out.println(text.contains(".*123")); // false (not regex)

Wenn Sie teilbasierte Übereinstimmungen mit regulären Ausdrücken wünschen, verwenden Sie die Klasse Pattern:

4-4. Zusammenfassung des Funktionsvergleichs

MethodPurposeReturn TypeRegex SupportUse Case
contains()Partial matchbooleanNoKeyword search
equals()Exact matchbooleanNoID/password checks
indexOf()Get match positionintNoIndex-based processing
matches()Regex matchbooleanYesFind pattern-based strings

5. Häufige Anwendungsfälle und Beispielcode

Die contains()‑Methode von Java ist einfach, wird aber in realen Entwicklungsszenarien häufig eingesetzt.
Typische Anwendungsfälle umfassen die Validierung von Benutzereingaben, Log‑Analyse und Filteroperationen.
Dieser Abschnitt behandelt praktische Beispiele mit zugehörigem Code.

5-1. Validierung von Benutzereingaben (Erkennung verbotener Wörter)

In Formularen oder Chat‑Anwendungen müssen Sie möglicherweise erkennen, ob bestimmte verbotene Wörter enthalten sind.

String input = "このアプリは最悪だ";
String banned = "最悪";

if (input.contains(banned)) {
    System.out.println("不適切な言葉が含まれています。");
}

Verarbeitung mehrerer NG‑Wörter:

List<String> bannedWords = Arrays.asList("最悪", "バカ", "死ね");
for (String word : bannedWords) {
    if (input.contains(word)) {
        System.out.println("不適切な言葉が含まれています: " + word);
        break;
    }
}

5-2. Logdateianalyse (Erkennung spezifischer Meldungen)

Beim Analysieren von System‑ oder Anwendungsprotokollen möchten Sie möglicherweise nur Zeilen extrahieren, die bestimmte Schlüsselwörter wie ERROR oder WARN enthalten.

List<String> logs = Arrays.asList(
    "[INFO] サーバーが起動しました",
    "[ERROR] データベース接続失敗",
    "[WARN] メモリ使用率が高い"
);

for (String log : logs) {
    if (log.contains("ERROR")) {
        System.out.println("エラー発生ログ: " + log);
    }
}

5-3. Filtern von Zeichenketten in einer Liste (mit Stream API)

Bei der Verarbeitung großer Datensätze verwenden Sie die Stream API, um nur Elemente zu extrahieren, die eine bestimmte Teilzeichenkette enthalten:

List<String> users = Arrays.asList("tanaka@example.com", "sato@gmail.com", "yamada@yahoo.co.jp");

List<String> gmailUsers = users.stream()
    .filter(email -> email.contains("@gmail.com"))
    .collect(Collectors.toList());

System.out.println(gmailUsers); // [sato@gmail.com]

5-4. Parsen von HTTP‑Anforderungs‑Headern oder URLs

In der Webentwicklung können Routing‑ oder gerätespezifische Handhabungen das Prüfen von Teilzeichenketten im User‑Agent oder in der URL erfordern.

String userAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_0 like Mac OS X)";
if (userAgent.contains("iPhone")) {
    System.out.println("スマートフォンからのアクセスです。");
}

5-5. Überprüfen von Dateipfaden oder -erweiterungen

Um den Typ einer Datei anhand ihres Pfads zu bestimmen:

String filePath = "/usr/local/data/sample.csv";
if (filePath.contains(".csv")) {
    System.out.println("CSVファイルです。");
}

Hinweis:
Bei Dateierweiterungsprüfungen ist endsWith(".csv") häufig genauer.

Praktische Überlegungen

  • Wenden Sie Normalisierung an (z. B. toLowerCase(), trim()), wenn Genauigkeit erforderlich ist.
  • Bei groß angelegten Daten sollten Sie die Stream API oder reguläre Ausdrücke in Betracht ziehen.
  • Denken Sie daran, dass contains() eine Teilübereinstimmung ist – kombinieren Sie es mit anderen Bedingungen für sicherere Logik.

6. Leistungsüberlegungen

Obwohl die Methode contains() hervorragende Lesbarkeit und Einfachheit bietet, müssen Sie ihre Leistungswirkungen bei der Verarbeitung großer Datensätze oder wiederholten Vorgängen berücksichtigen.
Dieser Abschnitt erklärt die Verarbeitungs­kosten von contains() und alternative Ansätze für verbesserte Effizienz.

6-1. Internes Verhalten und Zeitkomplexität von contains()

Die Methode contains() durchsucht die Zielzeichenkette sequenziell von Anfang an, um die Teilzeichenkette zu finden.
Intern verwendet sie die Methode indexOf(), und ihre Worst‑Case‑Zeitkomplexität beträgt:

O(n * m)
– n = Länge der Zielzeichenkette
– m = Länge der gesuchten Zeichenkette

Beispiel für aufwändige Verarbeitung:

for (String line : hugeTextList) {
    if (line.contains("error")) {
        // processing
    }
}

Dies kann die Leistung erheblich beeinträchtigen, wenn es in großen Schleifen wiederholt wird.

6-2. Techniken zur Leistungsverbesserung bei häufigen Suchen

Bei wiederholter Verwendung von contains() in großen Datensätzen können die folgenden Techniken die Verarbeitungsgeschwindigkeit verbessern:

• Alle Zeichenketten im Voraus in Kleinbuchstaben umwandeln

Anstatt bei jedem Vergleich toLowerCase() aufzurufen, normalisieren Sie die Zeichenketten vorher:

List<String> normalizedList = originalList.stream()
    .map(String::toLowerCase)
    .collect(Collectors.toList());
• Verwenden Sie die Stream API mit parallel() für parallele Verarbeitung

Nutzen Sie CPU‑Kerne, um Suchen zu beschleunigen:

List<String> result = hugeTextList.parallelStream()
    .filter(line -> line.contains("keyword"))
    .collect(Collectors.toList());
• Verwenden Sie reguläre Ausdrücke für komplexe Suchmuster

Wenn die Bedingungen komplex sind und in einem Regex ausgedrückt werden können, könnte Pattern besser performen:

Pattern pattern = Pattern.compile("error|fail|fatal");
for (String log : logs) {
    if (pattern.matcher(log).find()) {
        // matched
    }
}

6-3. Überlegungen zur Speichereffizienz und Wiederverwendbarkeit

Operationen, die Strings häufig konvertieren – wie toLowerCase() oder substring() –, können viele unnötige String-Objekte erzeugen, was den Speicherverbrauch beeinflusst. Dies ist besonders wichtig für lang laufende Anwendungen oder serverseitige Verarbeitung. Wichtige Punkte:

  • Vermeiden Sie das Erstellen unnötiger String-Instanzen.
  • Für große Datensätze sollten Sie Puffern oder Chunk-Verarbeitung in Betracht ziehen.
  • Das Cachen wiederholter contains()-Ergebnisse kann die Leistung in bestimmten Fällen verbessern.

7. Vergleich mit anderen Programmiersprachen

Die contains()-Methode von Java bietet einfaches, zuverlässiges Substring-Matching, aber andere Sprachen bieten ähnliche Funktionen mit ihren eigenen Eigenschaften. Dieser Abschnitt vergleicht das Überprüfen von Substrings in Python, JavaScript und C#, um Unterschiede und Ähnlichkeiten hervorzuheben.

7-1. Python: Einfaches partielles Matching mit dem in-Operator

In Python können Sie die Einbeziehung eines Substrings mit dem in-Operator überprüfen:

text = "Hello, Python!"
if "Python" in text:
    print("含まれています")

Diese Syntax ist äußerst lesbar – fast wie natürliche Sprache – und erfordert minimale Lernaufwände. Unterschiede und Hinweise:

  • in ist ein Sprachoperator, keine Methode.
  • Python ist ebenfalls case-sensitive bei String-Vergleichen.
  • None löst eine Ausnahme aus; Null-Überprüfungen sind erforderlich.

7-2. JavaScript: Partielles Matching mit includes()

In JavaScript (ES6+) können Sie die includes()-Methode verwenden:

const text = "JavaScript is fun";
console.log(text.includes("fun")); // true

Diese Methode ist Java’s contains() sehr ähnlich und leicht mental migrierbar. Unterschiede und Hinweise:

  • Das Übergeben von undefined löst keine Ausnahme aus; es gibt einfach false zurück.
  • includes() funktioniert auch auf Arrays und erhöht dadurch ihre Vielseitigkeit.

7-3. C#: Contains() ähnlich wie in Java

C# bietet ebenfalls eine Contains()-Methode mit ähnlichem Verhalten wie in Java:

string text = "Welcome to C#";
bool result = text.Contains("C#");

Unterschiede und Hinweise:

  • C# Contains() ist standardmäßig case-sensitive, aber Sie können die Groß-/Kleinschreibung ignorieren, indem Sie StringComparison.OrdinalIgnoreCase verwenden.
  • Das Übergeben von null löst eine ArgumentNullException aus.

7-4. Vergleichstabelle über Sprachen hinweg

LanguageExample SyntaxCase SensitivityNotes
Java"abc".contains("a")SensitiveThrows exception on null
Python"a" in "abc"SensitiveMost intuitive syntax
JavaScript"abc".includes("a")SensitiveAlso works for arrays
C#"abc".Contains("a")Sensitive (configurable)Comparison mode can be chosen

Zusammenfassung: Wählen Sie die richtige Syntax für Ihren Anwendungsfall

Obwohl das Überprüfen von Substrings ein gängiges Anforderung in allen Sprachen ist, bietet jede Sprache ihre eigene Methode oder Syntax. Java’s contains() bietet Stabilität und Klarheit, was es gut für Unternehmenssysteme und wartbare Anwendungen geeignet macht. Sprachen wie Python und JavaScript bieten einfachere und prägnantere Syntax, die ideal für leichte Skripte oder schnelle Prototyping ist. Indem Sie sowohl die gemeinsamen Konzepte als auch die spezifischen Features jeder Sprache verstehen, können Sie sichereren und effizienteren Code in verschiedenen Sprachen schreiben.

8. Häufig gestellte Fragen (FAQ)

Im Folgenden finden Sie häufig gestellte Fragen zur contains()-Methode von Java – um knifflige Punkte zu verstehen und gängige Fallstricke zu vermeiden.

Q1. Ist contains() case-sensitive?

Ja, es ist case-sensitive. Zum Beispiel gibt "Java".contains("java") false zurück. Lösung:

String input = "Welcome to Java";
boolean result = input.toLowerCase().contains("java");

Q2. Wie kann ich partielle Matches mit regulären Ausdrücken überprüfen?

contains() unterstützt keine regulären Ausdrücke. Verwenden Sie stattdessen matches() oder die Pattern-Klasse. Beispiel (Überprüfung eines numerischen Musters):

import java.util.regex.Pattern;
import java.util.regex.Matcher;

String text = "注文番号: A123456";
Pattern pattern = Pattern.compile("A\d+");
Matcher matcher = pattern.matcher(text);

if (matcher.find()) {
    System.out.println("パターンに一致しました。");
}

Q3. Was passiert, wenn ich contains() auf null aufrufe?

Eine NullPointerException wird ausgelöst.

String target = null;
System.out.println(target.contains("test")); // Error

Lösung:

if (target != null && target.contains("test")) {
    System.out.println("含まれています。");
}

Q4. Was passiert, wenn ich einen leeren String („“ ) an contains() übergebe?

Es wird immer true zurückgegeben.

String text = "Java";
System.out.println(text.contains("")); // true

Obwohl dies Teil der offiziellen Spezifikation ist, ist dieses Verhalten selten nützlich und kann unerwartete Fehler verursachen, wenn leere Strings nicht beabsichtigt sind.

Q5. Kann contains() mehrere Schlüsselwörter gleichzeitig suchen?

Nein. Jeder Aufruf prüft nur ein Schlüsselwort.

String text = "本日はシステムエラーが発生しました";
if (text.contains("エラー") || text.contains("障害") || text.contains("失敗")) {
    System.out.println("問題が検出されました。");
}

Dynamischer Ansatz:

List<String> keywords = Arrays.asList("エラー", "障害", "失敗");
boolean found = keywords.stream().anyMatch(text::contains);

Q6. Wann sollte ich contains() gegenüber indexOf() verwenden?

contains() gibt einen booleschen Wert zurück, während indexOf() einen numerischen Index liefert.

  • Verwende contains(), wenn du einfach wissen möchtest, ob die Teilzeichenkette existiert.
  • Verwende indexOf(), wenn du zusätzlich die Position benötigst.
    String text = "Error: Disk full";
    if (text.contains("Error")) {
        int pos = text.indexOf("Error");
        System.out.println("Position: " + pos);
    }
    

9. Fazit

Die contains()-Methode von Java ist ein leistungsfähiges und praktisches Werkzeug, um zu bestimmen, ob eine bestimmte Teilzeichenkette in einem String enthalten ist.
Sie wird in vielen Szenarien breit eingesetzt, wie z. B. bei der Validierung von Benutzereingaben, der Protokollanalyse und der Datenfilterung.
In diesem Artikel haben wir behandelt:

  • Grundsyntax und Rückgabewerte
  • Groß-/Kleinschreibung und deren Handhabung
  • Umgang mit null und leeren Strings
  • Unterschiede zu anderen String-Vergleichsmethoden
  • Praktische Anwendungsfälle: Validierung, Log-Suche, Stream-Verarbeitung
  • Leistungsaspekte und Optimierungstechniken
  • Vergleich mit Python, JavaScript und C#
  • Häufig gestellte Fragen und Tipps zur Fehlersuche

Obwohl contains() intuitiv und vielseitig ist, sollte seine Verwendung in Fällen, die große Datensätze, häufige Aufrufe oder komplexe Suchbedingungen betreffen, sorgfältig bewertet werden.
Durch die Kombination von Normalisierung, Parallelverarbeitung, Regex und Caching-Strategien kannst du sowohl Performance als auch Lesbarkeit erhalten.
Da contains() grundlegend für die Arbeit mit Strings in Java ist, hoffen wir, dass dir dieser Artikel hilft, es sicherer und effektiver in deinen Entwicklungsprojekten zu nutzen.