Javaを使用してリスト内の要素を見つける方法
1. 概要
リスト内の要素を見つけることは、開発者として出会う非常に一般的なタスクです。
このクイックチュートリアルでは、Javaでこれを行うためのさまざまな方法について説明します。
参考文献:
2. セットアップ
CustomerPOJOを定義することから始めましょう。
public class Customer {
private int id;
private String name;
// getters/setters, custom hashcode/equals
}
そして、顧客のArrayList:
List customers = new ArrayList<>();
customers.add(new Customer(1, "Jack"));
customers.add(new Customer(2, "James"));
customers.add(new Customer(3, "Kelly"));
CustomerクラスのhashCodeとequalsをオーバーライドしていることに注意してください。
equalsの現在の実装に基づいて、同じidを持つ2つのCustomerオブジェクトは等しいと見なされます。
このcustomersのリストを途中で使用します。
3. Java APIを使用する
Java自体は、リスト内のアイテムを見つけるいくつかの方法を提供します。
-
containsメソッド
-
indexOf メソッド
-
An ad-hoc for loop、および
-
Stream API
3.1. contains()
Listは、containsというメソッドを公開します。
boolean contains(Object element)
名前が示すように、このメソッドは、リストに指定されたelement,が含まれている場合はtrueを返し、そうでない場合はfalseを返します。
したがって、リストに特定のアイテムが存在するかどうかを確認するだけでよい場合は、次のことができます。
Customer james = new Customer(2, "James");
if (customers.contains(james)) {
// ...
}
3.2. indexOf()
indexOfは、要素を見つけるためのもう1つの便利な方法です。
int indexOf(Object element)
このメソッドは、指定されたリストで指定されたelementが最初に出現するインデックスを返します。リストにelementが含まれていない場合は-1を返します。
したがって、論理的に、このメソッドが-1以外を返す場合、リストに要素が含まれていることがわかります。
if(customers.indexOf(james) != -1) {
// ...
}
この方法を使用する主な利点は、指定されたリスト内の指定された要素の位置を教えてくれることです。
3.3. 基本的なループ
しかし、要素に対してフィールドベースの検索を実行したい場合はどうでしょうか? 宝くじを発表し、特定のnameを勝者としてCustomerを宣言する必要があるとします。
このようなフィールドベースの検索の場合、反復処理を使用できます。
リストを反復処理する従来の方法は、Java’s looping構造の1つを使用することです。 各反復で、リスト内の現在のアイテムを探している要素と比較して、一致するかどうかを確認します。
public Customer findUsingEnhancedForLoop(
String name, List customers) {
for (Customer customer : customers) {
if (customer.getName().equals(name)) {
return customer;
}
}
return null;
}
ここで、nameは、指定されたcustomersのリストで検索している名前を指します。 このメソッドは、一致するnameを持つリストの最初のCustomerオブジェクトを返し、そのようなCustomerが存在しない場合はnullを返します。
3.4. Iteratorでループする
Iteratorは、アイテムのリストをトラバースできるもう1つの方法です。
前の例を使用して、少し調整するだけです。
public Customer findUsingIterator(
String name, List customers) {
Iterator iterator = customers.iterator();
while (iterator.hasNext()) {
Customer customer = iterator.next();
if (customer.getName().equals(name)) {
return customer;
}
}
return null;
}
そして、振る舞いは以前と同じです。
3.5. Java 8Stream API
Java 8以降、List.で要素を検索することもできます。
特定のリスト内の特定の条件に一致する要素を見つけるには、次のようにします。
-
リストのstream()を呼び出す
-
適切なPredicateを使用してfilter()メソッドを呼び出します
-
そのような要素が存在する場合はthe first element that matches the filter predicate wrapped in an Optionalを返すfindAny() constructを呼び出します**
Customer james = customers.stream()
.filter(customer -> "James".equals(customer.getName()))
.findAny()
.orElse(null);
便宜上、Optionalが空の場合、デフォルトでnullに設定されますが、これがすべてのシナリオで常に最良の選択であるとは限りません。
4. サードパーティのライブラリ
さて、Stream APIは十分すぎるほどですが、what should we do if we’re stuck on an earlier version of Java?
幸いなことに、Google GuavaやApache Commonsのような多くのサードパーティライブラリを使用できます。
4.1. Google Guava
Google Guavaは、ストリームでできることと同様の機能を提供します。
Customer james = Iterables.tryFind(customers,
new Predicate() {
public boolean apply(Customer customer) {
return "James".equals(customer.getName());
}
}).orNull();
Stream APIでできるように、オプションでnullの代わりにデフォルト値を返すことを選択できます。
Customer james = Iterables.tryFind(customers,
new Predicate() {
public boolean apply(Customer customer) {
return "James".equals(customer.getName());
}
}).or(customers.get(0));
上記のコードは、一致するものが見つからない場合、リストの最初の要素を選択します。
また、リストまたは述語のいずれかがnullの場合、GuavaはNullPointerExceptionをスローすることを忘れないでください。
4.2. Apache Commons
Apache Commonsを使用して、ほぼ同じ方法で要素を見つけることができます。
Customer james = IterableUtils.find(customers,
new Predicate() {
public boolean evaluate(Customer customer) {
return "James".equals(customer.getName());
}
});
ただし、いくつかの重要な違いがあります。
-
Apache Commonsは、nullリストを渡すと、null を返すだけです。
-
は、GuavaのtryFindのようなデフォルト値の機能を提供しません
5. 結論
この記事では、List, s内の要素を見つけるさまざまな方法を学びました。これは、迅速な存在チェックから始まり、フィールドベースの検索で終わります。
また、Java 8Streams APIの代替として、サードパーティライブラリのGoogle GuavaとApache Commonsも検討しました。
立ち寄っていただきありがとうございます。これらの例のすべてのソースを確認することを忘れないでください。over on GitHub.