如何使用Java在列表中查找元素

1.概述

在列表中查找元素是我們作為開發人員遇到的非常常見的任務。

在本快速教程中,我們將介紹使用Java的不同方法。

進一步閱讀:

檢查列表是否用Java排序

了解幾種用於檢查列表是否用Java排序的算法。

閱讀更多→

一行中的Java列表初始化

在本快速教程中,我們將研究如何使用單線初始化List。

閱讀更多→

2.設定

首先讓我們開始定義Customer POJO:

public class Customer {



 private int id;

 private String name;



 // getters/setters, custom hashcode/equals

 }

然後是一個ArrayList客戶:

List<Customer> customers = new ArrayList<>();

 customers.add(new Customer(1, "Jack"));

 customers.add(new Customer(2, "James"));

 customers.add(new Customer(3, "Kelly"));

請注意,我們在Customer類中重寫了hashCodeequals

根據我們當前的equals實現,兩個具有相同id Customer對象將被視為相等。

我們將一直使用此customers列表。

3.使用Java API

Java本身提供了幾種在列表中查找項目的方式:

  • contains方法
  • indexOf方法
  • 臨時for循環
  • Stream API

3.1。 contains()

List公開了一個名為contains的方法:

boolean contains(Object element)

顧名思義,如果列表包含指定的element,則此方法返回true element,否則返回false

因此,當我們需要檢查列表中是否存在特定項目時,我們可以:

Customer james = new Customer(2, "James");

 if (customers.contains(james)) {

 // ...

 }

3.2。 indexOf()

indexOf是查找元素的另一種有用方法:

int indexOf(Object element)

此方法返回給定列表中指定element的第一個匹配項的索引;如果列表不包含element ,則返回-1。

從邏輯上講,如果此方法返回的值不是-1,則我們知道列表包含元素:

if(customers.indexOf(james) != -1) {

 // ...

 }

使用此方法的主要優點是,它可以告訴我們指定元素在給定列表中的位置。

3.3。基本循環

現在,如果我們想對元素進行基於字段的搜索,該怎麼辦?例如,假設我們要宣布彩票,我們需要聲明一個具有特定nameCustomer作為中獎者。

對於此類基於字段的搜索,我們可以轉向迭代。

遍歷列表的傳統方法是使用Java的循環結構之一。在每次迭代中,我們將列表中的當前項目與我們要查找的元素進行比較,以查看是否匹配:

public Customer findUsingEnhancedForLoop(

 String name, List<Customer> customers) {



 for (Customer customer : customers) {

 if (customer.getName().equals(name)) {

 return customer;

 }

 }

 return null;

 }

這裡的name是指我們在給定的customers列表中搜索的名稱。此方法返回列表中具有匹配name的第一個Customer對象,如果不存在這樣的Customer ,則返回null

3.4。用Iterator循環

Iterator是我們遍歷項目列表的另一種方法。

我們可以簡單地以前面的示例為例進行調整:

public Customer findUsingIterator(

 String name, List<Customer> customers) {

 Iterator<Customer> iterator = customers.iterator();

 while (iterator.hasNext()) {

 Customer customer = iterator.next();

 if (customer.getName().equals(name)) {

 return customer;

 }

 }

 return null;

 }

因此,其行為與以前相同。

3.5。 Java 8 Stream API

從Java 8開始,我們還可以使用Stream API在List.查找元素List.

要在給定列表中找到匹配特定條件的元素,我們:

  • 在列表上調用stream()
  • 調用f ilter()以適當的方法Predicate
  • 調用findAny()構造,如果存在這樣的元素,則返回與包裝在Optional中的filter謂詞匹配的第一個元素
Customer james = customers.stream()

 .filter(customer -> "James".equals(customer.getName()))

 .findAny()

 .orElse(null);

為方便起見,在Optional為空的情況下,我們默認為null ,但這可能並不總是每種情況的最佳選擇。

4.第三方圖書館

現在,雖然Stream API綽綽有餘,但是如果停留在Java的早期版本上,我們該怎麼辦?

幸運的是,我們可以使用許多第三方庫,例如Google Guava和Apache Commons。

4.1。谷歌番石榴

Google Guava提供的功能類似於我們可以對流進行的操作:

Customer james = Iterables.tryFind(customers,

 new Predicate<Customer>() {

 public boolean apply(Customer customer) {

 return "James".equals(customer.getName());

 }

 }).orNull();

Stream API一樣,我們可以選擇返回默認值而不是null

Customer james = Iterables.tryFind(customers,

 new Predicate<Customer>() {

 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<Customer>() {

 public boolean evaluate(Customer customer) {

 return "James".equals(customer.getName());

 }

 });

但是有兩個重要的區別:

  1. 如果我們傳遞一個null列表,Apache Commons只會返回null
  2. 它 不提供像Guava的tryFind.這樣的默認值功能tryFind.

5.結論

在本文中,我們學習了在List, s中查找元素的各種方法,通過快速的存在性檢查進行打標,並通過基於字段的搜索完成操作。

我們還研究了第三方庫Google GuavaApache Commons ,它們是Java 8 Streams API的替代方法。

感謝您的光臨,並記得在GitHub上查看所有這些示例的資源