1. 導入:なぜこのメソッドが重要なのか
Javaで開発を行っていると、Listの中から特定の要素がどこにあるのかを探したい場面は頻繁に訪れます。単純なループで要素を一つずつ比較しても実現可能ですが、コードが冗長になり、可読性が低下します。
indexOfとlastIndexOfを活用することで、検索処理を1行に集約し、保守性の高いコードを書くことができます。本記事では、これらメソッドの基本から、現場で役立つ注意点までを解説します。
2. 基礎知識:検索の仕組み
indexOf(Object o)は、指定されたオブジェクトがリスト内で最初に現れる位置(インデックス)を、lastIndexOf(Object o)は、最後に現れる位置を返します。
内部的には、各要素に対して equals() メソッド を呼び出して比較を行っています。そのため、検索対象のクラスで適切に equals() と hashCode() がオーバーライドされていること が、正確な動作の前提条件となります。
3. 実装と解決策
これらのメソッドは、見つからない場合に -1 を返すのが大きな特徴です。この仕様を逆手に取り、if文で「要素の存在確認」と「位置の特定」を同時に行うのがスマートな実装です。
4. サンプルプログラム
以下のコードは、リストから特定の名前を探し、その位置を表示する例です。そのままコンパイルして動作確認が可能です。
import java.util.ArrayList;
import java.util.List;
public class ListSearchExample {
public static void main(String[] args) {
List
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Orange");
fruits.add("Banana"); // 重複する要素
// 最初の "Banana" の位置を取得
int firstIndex = fruits.indexOf("Banana");
System.out.println("最初のBananaのインデックス: " + firstIndex); // 1
// 最後の "Banana" の位置を取得
int lastIndex = fruits.lastIndexOf("Banana");
System.out.println("最後のBananaのインデックス: " + lastIndex); // 3
// 要素が存在しない場合のチェック
int melonIndex = fruits.indexOf("Melon");
if (melonIndex == -1) {
System.out.println("メロンはリストに含まれていません。");
}
}
}
5. 応用・注意点:現場での落とし穴
現場でこのメソッドを使う際に、以下の2点に注意してください。
1. nullの取り扱い:
Listにnullが含まれている場合、indexOf(null)を呼び出すと、最初に見つかったnullのインデックスを返します。逆に、nullが含まれていないリストで実行すると-1が返ります。NullPointerExceptionを意図せず発生させないよう、リストの内容がnullを許容するか確認しましょう。
2. パフォーマンス:
これらメソッドの計算量は O(n) です。リストのサイズが非常に大きい場合、何度も繰り返し検索を行うとパフォーマンスが低下します。もし検索が頻発する設計であれば、HashSetなどの検索に特化したコレクションへの変換や、別のデータ構造の検討が必要です。
また、Java 21から導入された Sequenced Collections を使っている場合でも、リストベースの検索はこのメソッドが基本となります。基本だからこそ、正確に使いこなすことがシニアエンジニアへの第一歩です。

コメント