Javaのcontainsメソッド徹底解説|使い方・注意点・他メソッドとの違いもわかりやすく解説

目次

1. はじめに:Javaにおける文字列検索の重要性

Javaでプログラミングを行う上で、文字列操作は非常に頻繁に登場する処理の一つです。ユーザーの入力をチェックしたり、ファイルの内容を解析したり、特定のキーワードを検索したりと、あらゆる場面で文字列の中に「特定の言葉が含まれているかどうか」を判定する必要があります。

こうしたニーズに応えるために、Javaにはcontains()という便利なメソッドが用意されています。このメソッドを使えば、ある文字列が別の文字列を部分一致で含んでいるかどうかを簡単に判定することが可能です。たとえば、あるエラーメッセージが特定のキーワードを含んでいるか調べたい場合、contains()を使えば1行で処理が完結します。

特にWebアプリケーションやAPI処理、ログ解析のように大量の文字列を扱う場面では、このcontains()メソッドの活用がコードの可読性や保守性を大きく向上させます。一方で、大文字と小文字の扱いやnullの可能性など、注意点も少なくありません。

この記事では、Javaのcontains()メソッドについて、基本的な使い方からよくある間違い、他のメソッドとの違い、さらには実践的な活用方法まで、順を追って詳しく解説していきます。初学者の方はもちろん、現場でJavaを使用している方にとっても役立つ内容を目指しますので、ぜひ最後までご覧ください。

2. contains()メソッドの基本構文と特徴

Javaのcontains()メソッドは、ある文字列が別の文字列を部分的に含んでいるかどうかを判定するためのメソッドです。非常にシンプルな構文でありながら、実用性が高く、日常的に使われる場面が多いのが特徴です。

基本構文

boolean result = 対象文字列.contains(検索文字列);

このメソッドは、Stringクラスに属しており、引数にはCharSequence型(通常はString)の値を取ります。戻り値はboolean型で、対象の文字列に引数で渡した文字列が含まれていればtrue、含まれていなければfalseが返されます。

サンプルコード

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

System.out.println(hasKeyword); // 出力結果: true

上記の例では、"programming"という文字列が対象の文字列の中に含まれているため、contains()trueを返します。

メソッドの特性

  • 部分一致のみを判定する:完全一致を判定したい場合は、equals()を使用する必要があります。
  • 大文字・小文字を区別する:例えば"Java""java"は異なるものとして扱われます(詳細は後述)。
  • 正規表現は使用できない:あくまで「文字列として含まれているか」を確認するためのメソッドであり、パターンマッチングを行いたい場合はmatches()Patternクラスの利用が必要です。

nullが引数や対象になった場合の挙動

contains()メソッドにnullを渡すと、NullPointerExceptionが発生します。たとえば以下のようなコードはエラーになります。

String text = null;
System.out.println(text.contains("test")); // 例外発生

また、対象の文字列自体がnullである場合にも同様の例外が発生します。そのため、contains()を使用する前には、必ずnullチェックを行うことが推奨されます。

3. 実用的な使用例と注意点

Javaのcontains()メソッドは、非常に直感的に使える便利な機能ですが、使い方を誤ると思わぬバグや非効率なコードにつながることがあります。この章では、基本的な使用例を示しつつ、注意すべきポイントについて詳しく解説します。

3-1. 基本的な使用例

以下のコードは、contains()を使って、対象の文字列に特定のキーワードが含まれているかどうかを調べるシンプルな例です。

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

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

このように、contains()はif文などと組み合わせて、条件分岐に活用されるケースが非常に多く見られます。

3-2. 大文字・小文字の区別(case-sensitive)

contains()メソッドは大文字と小文字を区別します。たとえば、次のコードはfalseを返します。

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

このようなケースでは、文字列をあらかじめ小文字または大文字に変換してから比較するのが一般的です。

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

この処理により、ユーザー入力などによるケースの違いを吸収できます。

3-3. nullや空文字の取り扱い

contains()において最も注意すべき点の一つが、nullの扱いです。引数または対象文字列のどちらかがnullの場合、NullPointerExceptionが発生します。

String text = null;
System.out.println(text.contains("test")); // 実行時エラー

このような事態を防ぐためには、次のように事前チェックを入れることが重要です。

if (text != null && text.contains("test")) {
    // 安全に処理を実行
}

なお、空文字("")を引数に渡した場合は常にtrueが返されるため、その挙動も把握しておくとよいでしょう。

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

ただし、この用途ではendsWith(".csv")の方がより厳密かつ適切なケースもあります。

3-4. 複数キーワードの検索には非対応

contains()は一度に1つのキーワードしか確認できません。複数のキーワードを含むかどうかを調べたい場合は、複数のcontains()を使うか、Stream APIを利用すると効率的です。

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

または、より動的に対応したい場合:

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

4. contains()とよく比較される他のメソッド

Javaには、文字列を比較したり、特定の文字列が存在するかをチェックするためのメソッドが複数存在します。contains()はその中でも「部分一致」を確認するために使われるメソッドですが、他にもよく似た用途で使用されるメソッドがあります。この章では、それぞれの特徴と使い分けについて整理します。

4-1. equals()との違い:完全一致か部分一致か

equals()は、2つの文字列がまったく同じかどうか(完全一致)を判定するメソッドです。一方、contains()は部分一致で文字列が含まれているかを判定します。

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

System.out.println(a.equals(b));      // true:完全一致
System.out.println(a.contains("av")); // true:部分一致

主な違い

比較内容equals()contains()
比較の対象完全一致部分一致
大文字小文字の区別ありあり
引数の型ObjectCharSequence

使い分けのポイント:入力値が正確に一致している必要がある場面(ID照合など)ではequals()を、部分的に含まれていればよい場面(キーワード検索など)ではcontains()を使いましょう。

4-2. indexOf()との違い:位置を取得できるかどうか

indexOf()も文字列の中に別の文字列が含まれているかを調べるために使えます。違いは、indexOf()は含まれていた場合にその開始位置(インデックス)を返すという点です。含まれていない場合は-1を返します。

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

この挙動を使って、実質的にcontains()と同じような判定を行うこともできます。

if (text.indexOf("Java") >= 0) {
    System.out.println("含まれています");
}

使い分けのポイント:インデックス情報が不要で単に「含まれているか」を調べたいなら、より読みやすいcontains()を使うのが適しています。

4-3. matches()との違い:正規表現の対応有無

matches()は、文字列が指定された正規表現と完全に一致するかどうかを判定するメソッドです。contains()は文字列そのものを含んでいるかを見るだけで、正規表現は使用できません。

String text = "abc123";
System.out.println(text.matches(".*123")); // true
System.out.println(text.contains(".*123")); // false(正規表現ではないため)

正規表現で部分一致を判定したい場合は、Patternクラスを使う方法が一般的です。

4-4. 各メソッドの機能比較まとめ

メソッド目的戻り値正規表現対応用途例
contains()部分一致boolean×単語検索、キーワード含有
equals()完全一致boolean×ユーザーID・パスワード一致判定
indexOf()部分一致の位置取得int×位置判定、カスタム処理
matches()正規表現一致boolean複雑な文字列パターンの検出

5. よく使われるユースケースとサンプルコード

Javaのcontains()メソッドは、シンプルでありながら多くの実践的な場面で利用されます。特に、ユーザー入力のチェックやログ解析、リストのフィルタ処理など、現場で役立つ使い道が豊富です。この章では、典型的なユースケースをいくつか取り上げ、具体的なコード例とともに解説します。

5-1. ユーザー入力のバリデーション(禁止ワードの検出)

フォームやチャットアプリなどでは、特定のNGワードや禁止語が含まれていないかをチェックする必要があります。

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

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

複数のNGワードを扱いたい場合は、リストとループを組み合わせると柔軟に対応できます。

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

5-2. ログファイルの解析(特定メッセージの検出)

システムログやアプリケーションログを解析する際、特定のキーワード(例:ERROR, WARN)を含む行だけを抽出したいことがあります。

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

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

5-3. リスト内文字列のフィルタ処理(Stream APIとの併用)

大量のデータを扱う際には、Stream APIを使って特定の文字列を含む要素だけを抽出することができます。コードが簡潔で読みやすくなり、パフォーマンスにも優れます。

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. HTTPリクエストのヘッダーやURL解析

Web開発では、リクエストURLやUser-Agentに特定の文字列が含まれているかを判定し、処理を分岐させることがあります。

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

5-5. ファイルパスや拡張子のチェック

ファイルの種類を簡易的に判定したい場合にも、contains()が使えます。

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

ただし、この用途ではendsWith(".csv")の方がより厳密かつ適切なケースもあります。

実務上のポイント

  • 正確性が必要な場合は補助処理を加えること(例:toLowerCase()trim()
  • 大量データにはStream APIや正規表現の使用も検討
  • あくまで部分一致なので、他の条件と組み合わせて使うと安全性が向上

6. パフォーマンスに関する考察

contains()メソッドは、コードの可読性と実装の簡潔さに優れる一方で、大量のデータを扱うシステムや繰り返し処理が発生する場面では、パフォーマンス面の影響も考慮する必要があります。この章では、contains()の処理コストや、より効率的な代替手法について解説します。

6-1. contains()の内部動作と時間計算量

contains()は、対象となる文字列(Stringオブジェクト)の中から、引数として渡された部分文字列を前方から順番にスキャンして探します。内部的にはindexOf()メソッドを利用しており、最悪計算量は O(n * m)(nは元の文字列の長さ、mは検索文字列の長さ)です。

たとえば以下のようなコードが大量のループで実行される場合、全体的な処理速度に影響する可能性があります。

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

6-2. 頻繁な検索が必要な場合の対策

大量データ中でのcontains()の多用は、以下のような工夫でパフォーマンスを向上させることができます。

・すべての文字列を事前に小文字化する

文字列を比較するたびにtoLowerCase()を呼ぶのではなく、事前に統一処理しておくことで、変換コストを削減できます。

List<String> normalizedList = originalList.stream()
    .map(String::toLowerCase)
    .collect(Collectors.toList());
・Stream APIとparallel()の併用

CPUコア数を活かして並列処理させることで、検索速度を向上できます。

List<String> result = hugeTextList.parallelStream()
    .filter(line -> line.contains("keyword"))
    .collect(Collectors.toList());
・定型パターンが複雑なら、正規表現で検索

部分一致より複雑なパターンでの検索が必要な場合は、PatternクラスとMatcherを使ったほうが高速な場合もあります(特に複雑な条件を1回で表現できる場合)。

Pattern pattern = Pattern.compile("error|fail|fatal");
for (String log : logs) {
    if (pattern.matcher(log).find()) {
        // マッチした処理
    }
}

6-3. メモリ効率と再利用性の観点から

文字列を頻繁に変換(toLowerCase()substring())するような処理では、不要な文字列インスタンスが多く生成されてメモリを圧迫することがあります。長時間稼働するアプリケーションや、サーバーサイドの処理では、こうした点にも注意が必要です。

  • 不要な文字列オブジェクトの生成を抑える
  • 大量データを扱う場合はバッファ処理やチャンク分割を検討
  • リストの先頭からcontains()を何度も呼ぶ処理はキャッシュを利用すると改善することもある

7. 他言語との比較(Javaとの違い)

Javaのcontains()メソッドは、シンプルな構文で文字列の部分一致を判定できる優れた機能ですが、他のプログラミング言語にも同様の機能があり、それぞれに特徴があります。この章では、Python、JavaScript、C#といった主要言語における文字列の部分一致機能と、Javaとの違いについて解説します。

7-1. Python:in演算子でシンプルな部分一致

Pythonでは、inという演算子を使って、非常に直感的に文字列の部分一致を確認できます。

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

この書き方は自然言語のように読みやすく、学習コストが非常に低いのが特徴です。また、inは文字列だけでなくリストや辞書などにも適用できるため、汎用性があります。

違いと注意点:

  • inは構文上の演算子であり、メソッドではない
  • 大文字小文字の区別はJavaと同様にあり
  • null(None)の扱いにおいては例外が出るため、事前確認は必要

7-2. JavaScript:includes()メソッドで部分一致を確認

JavaScript(ES6以降)では、includes()メソッドを使って部分一致をチェックできます。

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

構文もJavaのcontains()と非常に似ており、移行もしやすいです。

違いと注意点:

  • JavaScriptではundefinedを渡しても例外にはならないが、常にfalse
  • includes()は配列にも使える(文字列以外への応用が可能)

7-3. C#:Contains()メソッドはJavaに近い

C#でもContains()という同名のメソッドが用意されており、構文や使用感はJavaに非常に近いです。

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

違いと注意点:

  • C#のContains()はデフォルトで大文字小文字を区別しますが、StringComparison.OrdinalIgnoreCaseのようなオプションで無視可能
  • C#ではnullを渡すとArgumentNullExceptionが発生

7-4. 各言語の比較表

言語構文例大文字小文字の扱い備考
Java"abc".contains("a")区別するnullで例外発生
Python"a" in "abc"区別する最も直感的な構文
JavaScript"abc".includes("a")区別する配列にも使用可能
C#"abc".Contains("a")区別する(設定可)比較方法のオプション指定可

まとめ:用途に応じて適切な構文を選ぶ

どの言語でも「部分一致の判定」はよく使われる処理であり、それぞれの言語に合った方法が用意されています。Javaのcontains()は安定性と明確さがあり、特に業務システム開発や保守性の高いコードに適しています。一方で、PythonやJavaScriptのように直感的で簡潔な構文を持つ言語は、軽量スクリプトやプロトタイピングに向いているとも言えるでしょう。

言語間で共通の考え方を持ちつつ、各言語特有の違いや注意点を理解することで、より安全かつ効果的なコードが書けるようになります。

8. よくある質問(FAQ)

Javaのcontains()メソッドに関して、開発現場や学習中によく寄せられる疑問やつまずきやすいポイントをまとめました。理解を深め、より正確に使いこなすための参考にしてください。

Q1. contains()は大文字と小文字を区別しますか?

はい、区別します。
たとえば "Java".contains("java")false を返します。部分一致でも、アルファベットの大小が一致していなければ含まれていないと判定されます。

対策方法:

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

このように、toLowerCase()toUpperCase()で文字列を統一してから比較することで、大文字小文字を無視した検索が可能になります。

Q2. 正規表現で部分一致を判定したい場合はどうすればいいですか?

contains()正規表現には対応していません。
正規表現によるマッチングを行いたい場合は、matches()Patternクラスを使用します。

例:特定の数字パターンにマッチさせたい場合

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. nullに対してcontains()を使うとどうなりますか?

例外(NullPointerException)が発生します。

次のようなコードは実行時にエラーになります:

String target = null;
System.out.println(target.contains("test")); // エラー

対策方法: 事前にnullチェックを行ってからcontains()を使用しましょう。

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

Q4. 空文字(””)を渡すとどうなりますか?

常にtrueを返します。

Javaの仕様では、空文字はすべての文字列に含まれているとみなされるため、以下のようなコードはtrueになります。

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

ただし、実用上はこの挙動を利用する機会は少なく、意図せず空文字が使われている場合には、バグの原因になることもあります。

Q5. contains()で複数のキーワードを一度に検索できますか?

いいえ、1回のcontains()呼び出しでは1つのキーワードしか確認できません。
複数の文字列をチェックしたい場合は、||演算子で複数のcontains()を並べるか、Listとループを使う方法があります。

例:複数キーワードの検索

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

または、より動的に対応したい場合:

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

Q6. contains()indexOf()の使い分けは?

contains()は真偽値を返し、indexOf()はインデックス(数値)を返します。

  • 単に「含まれているかどうか」を知りたい → contains()
  • 含まれている場所(位置)も必要 → indexOf()
String text = "Error: Disk full";
if (text.contains("Error")) {
    int pos = text.indexOf("Error");
    System.out.println("Errorの位置:" + pos);
}

9. まとめ

Javaのcontains()メソッドは、文字列内に特定の部分文字列が含まれているかどうかをシンプルかつ効率的に判定できる非常に便利な機能です。実際の現場でも、ユーザー入力のチェック、ログの解析、データのフィルタリングなど、さまざまなシーンで日常的に使われています。

本記事では、以下の点について詳しく解説してきました。

  • 基本構文と戻り値の理解
  • 大文字小文字の扱いとその回避法
  • nullや空文字に関する注意点
  • 他の文字列操作メソッドとの違いと使い分け
  • 実践的な使用例(バリデーション、ログ検索、Stream処理など)
  • パフォーマンス面での留意点と最適化の工夫
  • PythonやJavaScript、C#との構文・特性比較
  • 開発現場でよくある質問と具体的な対応策(FAQ)

contains()は、直感的な使いやすさに加えて、多くの開発ケースに応用可能である一方、「大量のデータ」「頻繁な呼び出し」「高度な検索条件」といった要素がある場合は、その使い方を慎重に見極める必要があります。状況に応じて、文字列正規化、並列処理、正規表現、キャッシュ戦略などを組み合わせることで、パフォーマンスと可読性の両立を図ることができます。

Javaで文字列を扱う上で、contains()は避けて通れないメソッドです。今後の開発でより安全かつ効果的に利用できるよう、ぜひ本記事の内容を実践に活かしてみてください。