如何使用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
類中重寫了hashCode
和equals
。
根據我們當前的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。基本循環
現在,如果我們想對元素進行基於字段的搜索,該怎麼辦?例如,假設我們要宣布彩票,我們需要聲明一個具有特定name
的Customer
作為中獎者。
對於此類基於字段的搜索,我們可以轉向迭代。
遍歷列表的傳統方法是使用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());
}
});
但是有兩個重要的區別:
- 如果我們傳遞一個
null
列表,Apache Commons只會返回null
。 - 它 不提供像Guava的
tryFind.
這樣的默認值功能tryFind.
5.結論
在本文中,我們學習了在List, s
中查找元素的各種方法,通過快速的存在性檢查進行打標,並通過基於字段的搜索完成操作。
我們還研究了第三方庫Google Guava
和Apache Commons
,它們是Java 8 Streams
API的替代方法。