はじめに
Javaのcontainsメソッドは、文字列やコレクションに目的の値が含まれるかをtrueまたはfalseで判定する検索用メソッドです。初心者がプログラミングで条件分岐を書くとき、containsの戻り値をifに渡せると、入力チェック、一覧検索、キーワード判定を短いコードで組み立てられます。
その一方で、Javaの文字列検索では大文字と小文字、null、ArrayListとHashSetの違いを外すと、期待と違う判定になりやすいです。完全解説として、使い方、注意点、カスタマイズまでをサンプルコード中心に整理します。
- Java 21 / OpenJDK 21
- 標準ライブラリ:
java.lang、java.util、java.util.stream
String.containsとCollection.containsの違い- 初心者が間違えやすい
nullと大小文字の扱い - 複数キーワード、正規表現、
Map検索の使い方 Stream、Predicateを使った検索条件の作り方- containsメソッドを安全にカスタマイズする考え方
Javaのcontainsメソッドとは
結論から言えば、Javaのcontainsメソッドは「対象の中に指定した値が含まれるか」を調べるための判定処理です。文字列ならStringがCharSequenceを含むか、リストならListが要素を含むかを調べ、戻り値はbooleanになります。
公式ドキュメントによれば、Stringクラスのcontainsは指定された文字列シーケンスを含む場合にtrueを返します。そのため、Javaプログラミングで検索結果を条件分岐へ渡したい場面と相性がよい構造です。
containsメソッドの基本概念
これを文字列で使う場合、"Hello, world!".contains("world")は部分文字列の有無を判定すると理解できます。コレクションで使う場合、List<String>に"banana"があるかを調べるため、同じcontainsメソッドでも対象型によって内部の比較方法が変わります。
その違いを早くつかむには、String、List、Set、Mapを分けて見るのが現実的です。JavaのList型を学ぶと、containsがequals比較に依存する場面も理解しやすくなります。
| 対象 | 主なメソッド | 判定内容 | 戻り値 | 注意点 |
|---|---|---|---|---|
String | contains | 部分文字列を含むか | boolean | 大小文字を区別 |
ArrayList | contains | 同じ要素を含むか | boolean | equalsで比較 |
HashSet | contains | 集合に要素があるか | boolean | hashCodeも影響 |
Map | containsKey | キーがあるか | boolean | キー検索向き |
Map | containsValue | 値があるか | boolean | 値を走査しやすい |
Stream | anyMatch | 条件を満たす要素があるか | boolean | 条件式で制御 |
Pattern | matches | 正規表現に合うか | boolean | 部分一致には書き方が必要 |
一方、Mapにはそのままのcontainsではなく、containsKeyとcontainsValueが用意されています。公式のMapインターフェースでも、キーと値を分けた検索として扱われます。
💡 Tips: containsメソッドは、存在確認のためのbooleanを返す処理として覚えると整理しやすくなると覚えるとよいでしょう。取得位置や一致件数が必要な場合は、indexOf、filter、countなど別のAPIも候補になります。
基本的に、containsメソッドは「値を取り出す」処理ではなく「あるかどうかを知る」処理です。検索後に値そのものを使いたいなら、get、findFirst、Optionalなどを組み合わせると、判定と取得の責務を分けられます。
containsメソッドの詳細な使い方
containsメソッドの使い方は、対象が文字列かコレクションかで読み方が変わりますが、これは押さえたい点です。サンプルコードでは最小単位の検索から始め、初心者がつまずきやすい大小文字とnullも同じ流れで確認します。
サンプルコード1:基本的な文字列の検索
具体的には、String型のtargetに検索語keywordが含まれるかを調べます。Javaの文字列検索で最も短い形なので、完全解説の入り口として押さえたいサンプルコードです。
結果: 期待される出力はtrueです。targetの中にkeywordと同じ並びがあるため、containsの戻り値が真になります。
このとき、判定対象は単語の意味ではなく文字の連続です。そのため、worldの前後に記号や空白があっても、連続した並びが保たれていれば一致します。検索語の前後に余計な空白が混じる入力では、trimやstripで整えてから判定すると読みやすい処理になると考えられます。
サンプルコード2:リスト内の要素の検索
その使い方をListへ移すと、文字列の一部ではなく要素そのものが検索対象になります。ArrayListに入れた値を判定するため、Javaのコレクション処理を学ぶ初心者にも扱いやすい例です。
結果: 期待される出力はtrueです。fruitsに"banana"という要素があるため、List.containsが真を返します。
ただし、Listのcontainsメソッドは部分一致ではありません。"ban"を渡しても"banana"の一部としては扱われないので、部分検索が必要なら各要素に対してString.containsを使います。リストの要素が独自クラスの場合は、equalsの実装が検索結果に影響すると言えるでしょう。
サンプルコード3:大文字・小文字を区別せずに検索
一方、JavaのString.containsは大文字と小文字を区別します。検索条件をゆるめたい場合は、対象と検索語をtoLowerCase()またはtoUpperCase()で同じ形にそろえてから判定します。
結果: 期待される出力はtrueです。targetとkeywordを小文字へ変換してから比較するため、WorldとWORLDの表記差が消えます。
このとき、言語ごとの大文字小文字変換を厳密に扱う用途ではLocaleの指定も検討します。英数字中心の検索なら十分な場面が多いものの、多言語入力では変換結果が想定と違う可能性があるのが基本です。特にユーザー名、メールアドレス、タグ検索では、保存時に正規化するか検索時に正規化するかを先に決めると、後続の処理が安定するのが基本です。
サンプルコード4:nullを考慮した検索方法
ただし、targetがnullの状態でcontainsメソッドを呼ぶとNullPointerExceptionが発生します。検索語がnullの場合も扱いを決めておくと、入力値を受け取るプログラミングで例外を避けやすくなります。
結果: 期待される出力はfalseです。&&は左から評価されるため、target != nullが偽になった時点でtarget.contains(keyword)は呼ばれません。
この書き方は短いですが、条件が増えると読みにくくなります。そのため、業務用コードではisPresentのような補助メソッドへ切り出し、nullの扱いを一箇所に寄せる設計も有効です。初心者は&&の短絡評価を理解しておくと、containsメソッド以外の例外対策にも応用できます。
サンプルコード5:部分文字列での検索
これまでの文字列検索は、すべて部分文字列の存在確認として動きますし、これが一つの目安です。たとえば"Javaプログラミング"に"プログラミング"が含まれるかを調べる場合、Javaのcontainsメソッドは自然な選択になります。
結果: 期待される出力はtrueです。substringの文字列がtargetの末尾側に連続して含まれているため、判定が真になります。
そのため、入力されたタグ、商品名、説明文の中に特定語が含まれるかを調べる処理へ応用できます。より複雑な条件が必要になったら、matchesやPatternへ切り替えると整理しやすくなるのが目安です。完全一致、前方一致、後方一致、部分一致を混同しないことが、検索ロジックを読みやすく保つための要点になるのが目安です。
containsは正規表現を解釈しません。".*Java.*"を渡してもパターンではなく通常の文字列として扱われるため、正規表現が必要な場合はmatchesやPatternを使います。containsメソッドの応用例
containsメソッドの応用では、単純な一致だけでなく、複数条件やデータ構造に合わせた判定が中心になります。JavaのプログラミングではStream、Map、正規表現を組み合わせると、検索処理の表現力が広がりますが、覚えておくと役立つでしょう。
サンプルコード6:リスト内の特定の条件を満たす要素の検索
一般に、リスト内の値そのものではなく「条件に合う要素があるか」を調べるなら、containsよりStream.anyMatchが読みやすくなります。Javaアノテーションのように要素へメタ情報が付く設計でも、条件判定の考え方は近いです。
結果: 期待される出力はtrueです。numbersには4と5があり、num > 3を満たす要素が少なくとも一つ存在します。
このサンプルコードではcontainsメソッドそのものではなく、同じ存在判定を条件式で表しています。値の完全一致ならcontains、条件付き検索ならanyMatchと使い分けると、コードの意図が伝わりやすくなるのがポイントです。条件の結果が一件でもあればよいのか、すべて満たす必要があるのかで、anyMatchとallMatchを選び分けますし、ここがポイントです。
サンプルコード7:文字列内の特定のパターンの検索
その延長として、文字列に複数の語が含まれるかを正規表現で調べる方法があります。matchesは文字列全体がパターンに合うかを判定するため、部分一致には前後へ.*を付けます。
結果: 期待される出力はtrueです。sentenceにJavaとPythonの両方が含まれるため、&&でつないだ判定が真になります。
ただし、固定文字列だけを調べるならcontainsメソッドのほうが単純です。正規表現は記号の意味を理解する必要があるため、初心者はcontainsで足りる条件かを先に確認すると混乱を減らせます。複数語をすべて含む条件なら&&、どれか一語でよい条件なら||を使うと意図が明確になるのが一般的です。
サンプルコード8:マップのキー・値の検索
一方、Mapはキーから値を取り出す構造なので、検索もcontainsKeyとcontainsValueに分かれます。キーを調べる処理は高速に扱われることが多く、値の検索は値全体を確認する設計になります。
結果: 期待される出力はhasAppleKey: trueとhasValue200: trueです。mapにはappleというキーと200という値が登録されています。
このサンプルコードでは、containsメソッドの考え方をMap向けのAPIへ置き換えています。キーで引く用途ならcontainsKey、値の存在だけを知りたい用途ならcontainsValueを選びますし、ここを基本と考えるとよいでしょう。キーに対して値を取得したい場合は、containsKeyだけでなくgetやgetOrDefaultも候補になるのがポイントです。
サンプルコード9:複数の検索キーワードを使用
これらの考え方は、複数キーワードの検索にもそのまま使えます。配列の各要素をforで取り出し、同じtextに対してcontainsを繰り返す構成です。
結果: 期待される出力は、Java、プログラミング、企業の各語を含む行です。keywordsに入った語がすべてtextに存在するため、三行分の出力が想定されます。
この構成は入力チェックや禁止語チェックへ応用できます。ただし、キーワードが多い場合はList化してstream()を使うと、全件一致か一部一致かをallMatchやanyMatchで表しやすくなるのが現実的です。検索語を外部ファイルから読む場合は、空文字や重複語を先に除くと判定の意味がぶれにくくなるのが一般的です。
サンプルコード10:高度なフィルタリングを伴う検索
具体的には、オブジェクトのプロパティを見ながら絞り込む処理でもcontainsメソッドを使えます。名前に特定文字が含まれるか、年齢が条件を満たすかをfilterにまとめる例です。
結果: 期待される出力はBobとCharlieに対応するPerson情報です。Bobは年齢条件を満たし、CharlieもgetAge() >= 30に一致します。
ただし、getName().contains("b")は小文字のbだけを探します。Bobの先頭は大文字Bなので、この条件だけでは一致せず、年齢条件によって抽出される点が注意点です。
このような検索は、顧客一覧、商品一覧、設定一覧のフィルタリングに近い形です。Javaのオーバーライドを理解しておくと、toStringやequalsの扱いも読みやすくなると整理できます。独自クラスの検索では、表示用のtoStringと同一性判定用のequalsを混同しないことも大切になります。
注意点と対処法
containsメソッドの注意点は、判定ルールが単純なぶん、前処理を省くと失敗しやすいところにあります。大文字と小文字、null、データ構造ごとの計算量を分けて確認すると、初心者でも安全な使い方へ近づけますし、ここがポイントです。
大文字・小文字の取り扱い
JavaのString.containsは、Helloとhelloを別の文字列として扱います。ユーザー入力の検索では、この差が想定外のfalseにつながることがあります。
結果: 期待される出力は一行目がfalse、二行目がtrueです。helloは先頭の大小文字が違うため一致せず、Helloは同じ並びとして見つかります。
そのため、大小文字を無視したい検索では、比較前に両方の文字列を同じ形式へ変換します。Javaのエスケープ処理と同じく、文字列は見た目と内部表現を分けて考えると扱いやすくなると理解できます。
結果: 期待される出力はtrueです。str.toUpperCase()と"HELLO".toUpperCase()を比較するため、大小文字の差を吸収できます。
この変換は検索前の正規化と考えられます。たとえば記事タイトル、ユーザー入力、ファイル名の検索では、保存された文字列の形と検索語の形がずれることがあるため、比較条件を明示すると読み手に意図が伝わりますが、これは押さえたい点です。
null値の取り扱い
一方、nullは空文字""とは別物です。nullの参照に対してメソッドを呼び出すと例外になるため、containsメソッドの前に入力値の有無を確認します。
結果: 期待される出力はNot Found or search string is nullです。search != nullが偽になるため、str.contains(search)は評価されません。
このような注意点は、フォーム入力や外部ファイルの読み込みで特に表れます。Objects.nonNull、Optional、早期returnを使う設計もありますが、単純な分岐ではsearch != nullで十分な場合があります。検索対象のstrもnullになり得るなら、str != nullを先に置く順序が必要になるのが現実的です。
特定のデータ構造における振る舞い
同じcontainsメソッドでも、ArrayListとHashSetでは検索の考え方が異なると覚えるとよいでしょう。ArrayListは順に探す構造になりやすく、HashSetはハッシュ値を使った集合検索として扱われます。
結果: 期待される出力はArrayList: ...msとHashSet: ...msの二行です。時間値は環境や負荷で変わるため、固定の数値として扱わないのが適切です。
公式のCollectionインターフェースでは、コレクションが要素群を表す基盤として定義されています。そのため、Javaではデータ構造を選ぶ段階で検索頻度、重複可否、順序の必要性を合わせて考えます。
System.currentTimeMillis()の値だけで性能を断定せず、実運用の判断ではJVMのウォームアップ、入力件数、データ分布も考慮すると考えられます。これらの注意点を踏まえると、小さなリストでは読みやすさを優先し、重複を許さず検索回数が多い場合はHashSetを検討する流れになります。Setを使う場合は順序が不要か、重複が落ちても問題ないかを確認してから置き換えるのが実用的です。
カスタマイズ方法
カスタマイズが必要になるのは、containsメソッドの戻り値だけでは情報が足りない場面です。存在確認だけでなく位置を取りたい、独自条件で判定したい、複数の属性をまとめて調べたい場合は、補助メソッドやラムダ式を使います。
ただし、標準APIで足りる処理まで独自実装に置き換えると、保守の負担が増えますし、これが一つの目安です。完全解説としては、標準の使い方を軸にしつつ、必要な部分だけカスタマイズする方針が扱いやすいです。
独自のcontainsメソッドの作成
具体的には、検索語が含まれるかだけでなく開始位置も返したい場合、intを返す補助メソッドを作れます。標準のindexOfでも近い処理はできますが、学習用には探索の流れを明示したサンプルコードが理解に役立ちます。
結果: 期待される出力は4です。"Javaプログラミング"では"プロ"がインデックス4から始まるため、その位置が返ります。
このカスタマイズでは、見つからない場合に-1を返しています。JavaのString.indexOfと似た約束にしておくと、ほかの開発者が戻り値の意味を推測しやすくなると言えるでしょう。独自メソッドでは、haystackやneedleがnullのときに例外にするのか、-1を返すのかも決めておく必要があると整理できます。
indexOfを先に検討します。独自のcontainsメソッドは、特殊な比較条件や学習目的がある場合に限定すると管理しやすくなるのが基本です。ラムダ式を使用した柔軟な検索条件の適用
そのカスタマイズをコレクションへ広げるなら、Predicateを受け取るメソッドが使えます。Java 8以降のラムダ式を使うと、検索条件を呼び出し側から渡せるため、年齢、名前、数値範囲などの条件を一つの形で扱えます。
結果: 期待される出力はtrueです。listには3と4が含まれ、ラムダ式x -> x > 2を満たす値が存在します。
この使い方はStream.anyMatchに近い発想です。独自メソッドにする理由が薄い場合は標準のstream().anyMatch(predicate)を選び、独自の前処理やログ出力が必要な場合だけラッパー化すると保守しやすくなります。
使い分けると、標準APIで済む検索は短く書き、業務ルールを含む検索だけをカスタマイズできるのが目安です。Javaのうるう年判定のような条件分岐の練習と合わせると、Predicateに渡す判定式も組み立てやすくなります。
その設計では、メソッド名も戻り値に合わせると読みやすくなります。lambdaContainsがbooleanを返すなら存在確認に限定し、抽出した要素を返す場合はfilterByやfindByのような名前に分けると、使い方の誤解を避けられますが、覚えておくと役立つでしょう。
まとめ
Javaのcontainsメソッドは、文字列では部分文字列、コレクションでは要素の存在をbooleanで返す検索処理です。完全解説として見ると、単体の使い方だけでなく、List、Set、Map、Streamの役割を分けることが理解の近道になります。
そのため、初心者はString.containsで文字列検索を確認し、次にList.containsで要素検索へ進むと整理しやすくなります。大文字小文字、null、データ構造の違いは注意点として早めに押さえると、プログラミング中の予期しないfalseや例外を減らせますし、ここを基本と考えるとよいでしょう。
一方、標準のcontainsメソッドで足りない場合は、indexOf、matches、anyMatch、Predicateを組み合わせます。カスタマイズは目的を絞るほど読みやすくなり、サンプルコードのように戻り値の意味を明確にすると保守しやすくなります。
これらを踏まえると、Javaで検索処理を書くときは「何を含むか」「完全一致か部分一致か」「例外を避ける前処理があるか」を先に決めるのが実用的です。containsメソッドの使い方を軸にすれば、条件分岐からフィルタリングまで一貫した考え方で組み立てられますし、ここがポイントです。
Javaプログラミングでは、短い判定式ほど読みやすく見える反面、大小文字、空白、null、データ構造の性質が結果を左右します。完全解説のサンプルコードを基準に、検索対象と戻り値の意味を確認しながら書けば、初心者でもcontainsメソッドを実用的な部品として扱えます。
関連記事
- Java List型完全ガイド!初心者でもマスターできる7つのステップ
- Javaアノテーションの12選!初心者から上級者まで徹底ガイド
- Javaでうるう年を判定!初心者でも分かる9ステップ解説
- Javaエスケープ処理の10ステップマスターガイド
- Javaでマスターする!オーバーライドのたった7つのステップ
※本記事は実在のエンジニア複数名で構成される Japanシーモア編集部が、AI支援を活用して作成・校正・公開しています。


