はじめに
この記事を読めばJavaのcontainsメソッドをマスターすることができるようになります。
Javaのcontainsメソッドは、文字列やコレクションなどに特定の要素が存在するかどうかを調べる際に非常に便利です。
プログラミング初心者の方でも、この記事で疑問点をクリアにできるでしょう。
また、より経験豊富な方にとっても、いくつかの新しい発見があるかもしれません。
●Javaのcontainsメソッドとは
Javaプログラミング言語には多くの便利なメソッドがありますが、その中でも「containsメソッド」は特によく使われるものの一つです。
このメソッドは主に、文字列やリスト、セットなどのコレクションに特定の要素が含まれているかどうかを確認するために使用されます。
○containsメソッドの基本概念
containsメソッドは、あるオブジェクトが特定の要素を持っているかどうかを確認する際に用いられます。
具体的には、文字列が特定の文字列を部分文字列として含むか、リストが特定の要素を含むかなどを調べます。
結果として真偽値(trueまたはfalse)が返されるのが一般的です。
このメソッドは次のような形で使用されます。
- 文字列の場合:
"Hello, world!".contains("world")
このコードはtrue
を返します。 - リストの場合:
List<String> list = Arrays.asList("apple", "banana", "cherry");
で、list.contains("banana")
とするとtrue
が返されます。
●containsメソッドの詳細な使い方
containsメソッドの用途と基本的な使い方を知ったところで、ここからはより詳細な使い方をサンプルコードと共に解説していきます。
○サンプルコード1:基本的な文字列の検索
最も一般的な用途として、文字列中に特定の文字列が含まれているかどうかを確認するケースがあります。
ここでは、文字列"Hello, world!"
から"world"
が含まれているかどうかを確認してみましょう。
public class Main {
public static void main(String[] args) {
// 対象となる文字列
String target = "Hello, world!";
// 検索したい文字列
String keyword = "world";
// containsメソッドで検索
boolean result = target.contains(keyword);
// 結果の出力
System.out.println(result); // trueが出力される
}
}
このコードは、"Hello, world!"
という文字列に"world"
が含まれているかどうかをcontains
メソッドで検証しています。
contains
メソッドは真偽値を返すので、この例ではtrue
が出力されます。
○サンプルコード2:リスト内の要素の検索
次に、Listコレクションにおいて、特定の要素が存在するかどうかを調べる方法について見ていきます。
ArrayList
に"apple"
、"banana"
、"cherry"
という要素が含まれているかどうかを確認するJavaプログラムを紹介します。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
// ArrayListの作成と初期化
List<String> fruits = new ArrayList<>(Arrays.asList("apple", "banana", "cherry"));
// "banana"が含まれているか確認
boolean result = fruits.contains("banana");
// 結果の出力
System.out.println(result); // trueが出力される
}
}
このJavaプログラムでは、ArrayList
に対してcontains
メソッドを使っています。
"banana"
はリストfruits
に含まれているので、結果としてtrue
が出力されます。
○サンプルコード3:大文字・小文字を区別せずに検索
文字列の検索においては、大文字と小文字を区別せずに検索を行いたい場合が多々あります。
Javaのcontainsメソッドは大文字と小文字を区別してしまうので、この要件を満たすには少し工夫が必要です。
public class Main {
public static void main(String[] args) {
// 対象の文字列
String target = "Hello, World!";
// 検索キーワード
String keyword = "WORLD";
// 大文字小文字を区別せずに比較
boolean result = target.toLowerCase().contains(keyword.toLowerCase());
// 結果を出力
System.out.println(result); // trueが出力されます。
}
}
このコード例では、toLowerCase()
メソッドを用いて対象の文字列と検索キーワードの両方を小文字に変換しています。
その上で、contains
メソッドを適用しています。
これにより、大文字・小文字を区別せずに検索が可能となります。
このコードを実行すると、”true”が出力され、大文字・小文字を無視した状態で”World”が”Hello, World!”に含まれていることが確認できます。
○サンプルコード4:nullを考慮した検索方法
Javaのcontainsメソッドは、対象または検索キーワードがnullの場合にはNullPointerExceptionが発生します。
したがって、nullチェックが必要となります。
public class Main {
public static void main(String[] args) {
// 対象の文字列がnull
String target = null;
// 検索キーワード
String keyword = "hello";
// nullチェックをしてからcontainsメソッドを使用
boolean result = (target != null && keyword != null) && target.contains(keyword);
// 結果を出力
System.out.println(result); // falseが出力されます。
}
}
このコードでは、target
とkeyword
のいずれもnullでないことを確認した上でcontains
メソッドを実行しています。
その結果、target
がnullであるため、false
が出力されます。
このようにして、null値が存在する場合も安全にcontains
メソッドを用いることができます。
○サンプルコード5:部分文字列での検索
Javaのcontainsメソッドは、文字列が別の文字列に含まれているかどうかを調べるものですが、この場合の「含まれている」というのは「部分文字列として存在する」という意味でもあります。
例えば、”Javaプログラミング”という文字列が”プログラミング”を部分文字列として持っている場合、containsメソッドはtrueを返します。
部分文字列の検索には次のようなコードを使います。
public class Main {
public static void main(String[] args) {
// 対象の文字列
String target = "Javaプログラミング";
// 検索する部分文字列
String substring = "プログラミング";
// containsメソッドで部分文字列の検索
boolean result = target.contains(substring);
// 結果の出力
System.out.println(result); // trueと出力されます
}
}
このコードでは対象となる文字列target
に対して、contains
メソッドを使用しています。
検索したい部分文字列substring
がtarget
に含まれているかどうかを調べています。
コードを実行すると、true
が出力されます。
これは”プログラミング”が”Javaプログラミング”に部分文字列として存在するためです。
●containsメソッドの応用例
containsメソッドは非常にシンプルながらも、その応用範囲は広いです。
特定の条件を満たす要素があるかどうかをリストで検索したり、文字列内で特定のパターンが存在するかどうかを調べることなど、多くのケースで活用できます。
○サンプルコード6:リスト内の特定の条件を満たす要素の検索
一般的なリストの要素検索と異なり、特定の条件を満たす要素が存在するかどうかを確認する際にもcontainsメソッドが利用できます。
ただし、この場合はJava 8以上のStream APIを活用すると効率的です。
import java.util.Arrays;
import java.util.List;
public class App {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean exists = numbers.stream().anyMatch(num -> num > 3);
System.out.println(exists); // 結果はtrue
}
}
このコードではJavaのStream APIを使用して、リストnumbers
内に3より大きい数字が存在するかどうかを確認しています。
anyMatch
メソッドとラムダ式を組み合わせて、特定の条件を満たす要素が一つでもある場合はtrueを返しています。
実行結果としては、4と5が条件を満たすためtrueが出力されます。
○サンプルコード7:文字列内の特定のパターンの検索
containsメソッドは単純な部分文字列の検索に使われることが多いですが、正規表現と組み合わせることで、特定のパターンが文字列に含まれているかどうかも確認できます。
public class App {
public static void main(String[] args) {
String sentence = "私はJavaとPythonが好きです。";
boolean result = sentence.matches(".*Java.*") && sentence.matches(".*Python.*");
System.out.println(result); // 結果はtrue
}
}
こちらのコードでは、文字列sentence
が”Java”と”Python”という両方の単語を含むかどうかを調べています。
matches
メソッドを使用して正規表現でマッチングを行い、その結果を論理演算子&&
で繋げています。
このようにして、特定の複数のパターンが存在するかどうかを一度の処理で確認しています。
この場合も、実行結果はtrueが出力されます。
○サンプルコード8:マップのキー・値の検索
JavaのMapインターフェースには、特定のキーまたは値がマップ内に存在するかどうかを確認するためのcontainsKey
とcontainsValue
メソッドがあります。
これらのメソッドは、containsメソッドの考え方をマップに適用したものと言えます。
import java.util.HashMap;
import java.util.Map;
public class App {
public static void main(String[] args) {
// キーと値を持つマップを作成
Map<String, Integer> map = new HashMap<>();
map.put("apple", 100);
map.put("banana", 200);
map.put("cherry", 300);
// キーで検索
boolean hasAppleKey = map.containsKey("apple");
// 値で検索
boolean hasValue200 = map.containsValue(200);
System.out.println("hasAppleKey: " + hasAppleKey); // 結果はtrue
System.out.println("hasValue200: " + hasValue200); // 結果はtrue
}
}
このJavaプログラムでは、まずHashMap
を用いてキーと値のペアを保持するマップを生成しています。
その後、containsKey
メソッドを使って”apple”というキーがマップに存在するかを確認し、containsValue
メソッドで200という値がマップに存在するかを確認しています。
このプログラムを実行すると、”apple”というキーが存在し、200という値も存在するため、両方とも結果はtrueとなります。
○サンプルコード9:複数の検索キーワードを使用
複数の検索キーワードがある場面でも、containsメソッドは有用です。
次の例では、配列に複数の検索キーワードが格納されている状況を考えます。
public class App {
public static void main(String[] args) {
String text = "Javaはプログラミング言語の一つであり、多くの企業で採用されています。";
String[] keywords = {"Java", "プログラミング", "企業"};
for (String keyword : keywords) {
if (text.contains(keyword)) {
System.out.println("テキストは " + keyword + " を含む"); // Java、プログラミング、企業をそれぞれ含むと出力される
}
}
}
}
このプログラムでは、text
という文字列内にkeywords
という文字列配列に格納された各キーワードが含まれるかどうかを確認しています。
このように複数の検索キーワードを効率よく処理する際にもcontainsメソッドが役立ちます。
プログラムの実行結果としては、”Java”、”プログラミング”、”企業”というキーワードが全てtext
に含まれているため、それらがそれぞれ出力されます。
○サンプルコード10:高度なフィルタリングを伴う検索
さて、Javaのcontainsメソッドを用いた高度なフィルタリングについて見ていきましょう。
具体的には、リスト内のオブジェクトが特定の条件を満たすものだけを抽出するケースを考えます。
このような場合には、containsメソッドだけでなく、Stream APIとの組み合わせが非常に便利です。
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class App {
public static void main(String[] args) {
// Personオブジェクトのリストを作成
List<Person> people = new ArrayList<>();
people.add(new Person("Alice", 25));
people.add(new Person("Bob", 30));
people.add(new Person("Charlie", 35));
// 名前に'b'が含まれる、または年齢が30以上のPersonオブジェクトをフィルタリング
List<Person> filteredPeople = people.stream()
.filter(p -> p.getName().contains("b") || p.getAge() >= 30)
.collect(Collectors.toList());
// 結果を出力
for (Person p : filteredPeople) {
System.out.println(p);
}
}
}
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';
}
}
このプログラムでは、まずPerson
クラスのオブジェクトをいくつか作成してリストに格納しています。
その後、Stream APIのfilter
メソッドを用いて、特定の条件を満たすPerson
オブジェクトだけを新しいリストに格納しています。
ここでの条件は、getName().contains("b")
(名前に「b」が含まれる)またはgetAge() >= 30
(年齢が30以上)です。
このように、containsメソッドは高度なフィルタリングを行う際にも役立つメソッドであることがわかります。
プログラムを実行すると、filteredPeople
リストには、名前に「b」が含まれるか、または年齢が30以上のPerson
オブジェクトが格納されます。
具体的には、”Bob”, “Charlie”という名前のPersonオブジェクトが出力される結果となります。
●注意点と対処法
containsメソッドは非常に便利ですが、使い方によっては予期せぬ問題が発生する可能性があります。
そこでここでは、注意が必要なポイントとその対処法について説明します。
○大文字・小文字の取り扱い
Javaのcontainsメソッドは大文字と小文字を区別します。
ですので、”Hello”と”hello”は異なるとみなされます。
public class Main {
public static void main(String[] args) {
String str = "Hello World";
System.out.println(str.contains("hello")); // false
System.out.println(str.contains("Hello")); // true
}
}
このコードを実行すると、最初の出力がfalse
で、次の出力がtrue
になります。
大文字・小文字を区別しない検索をしたい場合は、両方の文字列を大文字(または小文字)に変換してからcontainsメソッドを使用するとよいでしょう。
public class Main {
public static void main(String[] args) {
String str = "Hello World";
System.out.println(str.toUpperCase().contains("HELLO".toUpperCase())); // true
}
}
この場合、”HELLO”が含まれているかどうかを確認する前に、元の文字列と検索する文字列を両方とも大文字に変換しています。
結果、true
が出力されます。
○null値の取り扱い
containsメソッドでnull値が引数として渡された場合、NullPointerExceptionが発生します。
このような場合には事前にnullチェックを行うことが重要です。
public class Main {
public static void main(String[] args) {
String str = "Hello World";
String search = null;
if(search != null && str.contains(search)) {
System.out.println("Found");
} else {
System.out.println("Not Found or search string is null");
}
}
}
このコードでは、検索する文字列がnullかどうかを先に確認してからcontainsメソッドを使用しています。
このようにすることで、NullPointerExceptionを防ぐことができます。
コードを実行すると、”Not Found or search string is null”と出力されます。
○特定のデータ構造における振る舞い
JavaのCollections FrameworkにはArrayListやLinkedList、HashSetなど多くのデータ構造が存在しますが、containsメソッドは各データ構造で異なる時間計算量を持つことがあります。
import java.util.ArrayList;
import java.util.HashSet;
public class Main {
public static void main(String[] args) {
ArrayList<Integer> arrayList = new ArrayList<>();
HashSet<Integer> hashSet = new HashSet<>();
// 要素の追加
for (int i = 0; i < 100000; i++) {
arrayList.add(i);
hashSet.add(i);
}
// ArrayListとHashSetでの検索速度の比較
long start = System.currentTimeMillis();
arrayList.contains(99999);
long end = System.currentTimeMillis();
System.out.println("ArrayList: " + (end - start) + "ms");
start = System.currentTimeMillis();
hashSet.contains(99999);
end = System.currentTimeMillis();
System.out.println("HashSet: " + (end - start) + "ms");
}
}
このコードではArrayListとHashSetでの検索速度を比較しています。
ArrayListの場合は線形時間がかかる可能性がありますが、HashSetは定数時間で終わることが多いです。
実行すると、HashSetの方がArrayListよりも高速に検索できることが多いです。
●カスタマイズ方法
Javaのcontainsメソッドは非常に便利で多用されるメソッドですが、特定の状況によっては、その機能に制限を感じることもあるでしょう。そういった場合には、カスタマイズが可能です。
ここでは、独自のcontainsメソッドの作成方法と、ラムダ式を用いた柔軟な検索条件の設定について詳しく解説します。
○独自のcontainsメソッドの作成
基本的なcontainsメソッドには限りがあります。
例えば、特定の文字列が部分文字列として存在する場合に、その位置も同時に取得したいというようなケースが考えられます。
そのための独自のcontainsメソッドを紹介します。
public class CustomContains {
public static int customContains(String haystack, String needle) {
for (int i = 0; i <= haystack.length() - needle.length(); i++) {
if (haystack.substring(i, i + needle.length()).equals(needle)) {
return i;
}
}
return -1;
}
public static void main(String[] args) {
String str = "Javaプログラミング";
String search = "プロ";
int position = customContains(str, search);
System.out.println(position); // 4
}
}
このコードでは、haystack
(検索される文字列)とneedle
(検索する文字列)を引数に取り、needle
がhaystack
のどの位置で始まるかを返すcustomContains
メソッドを定義しています。
このメソッドを使用すると、特定の文字列が含まれている場合にその開始位置も取得できます。
上記の例では、”プロ”は”Javaプログラミング”の4文字目から始まるため、4
が出力されます。
○ラムダ式を使用した柔軟な検索条件の適用
Java 8以降、ラムダ式が使えるようになりました。
これにより、より柔軟な検索条件を独自に設定できます。
ArrayListの要素をフィルタリングする独自のcontainsメソッドの一例を紹介します。
import java.util.ArrayList;
import java.util.function.Predicate;
public class LambdaContains {
public static <T> boolean lambdaContains(ArrayList<T> list, Predicate<T> predicate) {
for (T item : list) {
if (predicate.test(item)) {
return true;
}
}
return false;
}
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
boolean result = lambdaContains(list, (Integer x) -> x > 2);
System.out.println(result); // true
}
}
このコードにおいて、lambdaContains
メソッドは、ArrayListとPredicateインターフェースを受け取ります。
Predicateは、テスト条件をラムダ式で表すことができます。
この例では、ArrayListの要素が2より大きい場合にtrueを返すラムダ式を使用しています。
結果として、ArrayListには3と4が2より大きいので、true
が出力されます。
まとめ
Javaのcontainsメソッドについて、その基本的な使用法から応用例、さらにはカスタマイズ方法に至るまで詳しく解説してきました。
この記事を通して、containsメソッドの多面的な使い方やその柔軟性を理解できたでしょう。
本記事が、Javaのcontainsメソッドを理解し、その機能を最大限に活用する一助となれば幸いです。
これからもJavaプログラミングにおいて、各種メソッドやテクニックを活用して、より高度なプログラムを目指しましょう。