具有Lambda表達式的Java流過濾器

1.簡介

在本快速教程中,我們將探討在Java中使用StreamsStream.filter()方法的使用。

我們將研究如何使用它,以及如何處理帶有已檢查異常的特殊情況。

2.使用Stream.filter()

filter()方法是Stream接口的中間操作,它使我們可以過濾與給定Predicate:匹配的流元素Predicate:

Stream<T> filter(Predicate<? super T> predicate)

要查看其工作原理,讓我們創建一個Customer類:

public class Customer {

 private String name;

 private int points;

 //Constructor and standard getters

 }

另外,讓我們創建一個客戶集合:

Customer john = new Customer("John P.", 15);

 Customer sarah = new Customer("Sarah M.", 200);

 Customer charles = new Customer("Charles B.", 150);

 Customer mary = new Customer("Mary T.", 1);



 List<Customer> customers = Arrays.asList(john, sarah, charles, mary);

2.1。篩選集合

filter()方法的一個常見用例是處理集合。

讓我們列出100 points.以上的客戶points.為此,我們可以使用lambda表達式:

List<Customer> customersWithMoreThan100Points = customers

 .stream()

 .filter(c -> c.getPoints() > 100)

 .collect(Collectors.toList());

我們還可以使用方法參考,它是lambda表達式的縮寫:

List<Customer> customersWithMoreThan100Points = customers

 .stream()

 .filter(Customer::hasOverHundredPoints)

 .collect(Collectors.toList());

在這種情況下,我們將hasOverHundredPoints方法添加到我們的Customer類中:

public boolean hasOverHundredPoints() {

 return this.points > 100;

 }

在這兩種情況下,我們都得到相同的結果:

assertThat(customersWithMoreThan100Points).hasSize(2);

 assertThat(customersWithMoreThan100Points).contains(sarah, charles);

2.2。使用多個條件過濾集合

此外,我們可以對filter()使用多個條件。例如,我們可以按pointsname過濾:

List<Customer> charlesWithMoreThan100Points = customers

 .stream()

 .filter(c -> c.getPoints() > 100 && c.getName().startsWith("Charles"))

 .collect(Collectors.toList());



 assertThat(charlesWithMoreThan100Points).hasSize(1);

 assertThat(charlesWithMoreThan100Points).contains(charles);

3.處理異常

到目前為止,我們一直在使用不會引發異常的謂詞的過濾器。實際上, Java中功能接口不會聲明任何檢查或未檢查的異常

接下來,我們將展示一些不同的方法來處理lambda表達式中的異常。

3.1。使用自定義包裝

首先,我們首先向我們的Customer添加一個profilePhotoUrl :

private String profilePhotoUrl;

另外,讓我們添加一個簡單的hasValidProfilePhoto()方法來檢查配置文件的可用性:

public boolean hasValidProfilePhoto() throws IOException {

 URL url = new URL(this.profilePhotoUrl);

 HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();

 return connection.getResponseCode() == HttpURLConnection.HTTP_OK;

 }

我們可以看到hasValidProfilePhoto()方法拋出IOException 。現在,如果我們嘗試使用這種方法過濾客戶:

List<Customer> customersWithValidProfilePhoto = customers

 .stream()

 .filter(Customer::hasValidProfilePhoto)

 .collect(Collectors.toList());

我們將看到以下錯誤:

Incompatible thrown types java.io.IOException in functional expression

為了處理它,我們可以使用的替代方法之一是用try-catch塊包裝它:

List<Customer> customersWithValidProfilePhoto = customers

 .stream()

 .filter(c -> {

 try {

 return c.hasValidProfilePhoto();

 } catch (IOException e) {

 //handle exception

 }

 return false;

 })

 .collect(Collectors.toList());

如果需要從謂詞中引發異常,則可以將其包裝在未經檢查的異常中,例如RuntimeException

3.2。使用ThrowingFunction

另外,我們可以使用ThrowingFunction庫。

ThrowingFunction是一個開放源代碼庫,允許我們處理Java功能接口中的已檢查異常。

首先,將throwing-function依賴項添加到pom中:

<dependency>

 <groupId>pl.touk</groupId>

 <artifactId>throwing-function</artifactId>

 <version>1.3</version>

 </dependency>

為了處理謂詞中的異常,該庫為我們提供了ThrowingPredicate類,該類具有unchecked()方法來包裝已檢查的異常。

讓我們看看它的作用:

List customersWithValidProfilePhoto = customers

 .stream()

 .filter(ThrowingPredicate.unchecked(Customer::hasValidProfilePhoto))

 .collect(Collectors.toList());

4。結論

在本文中,我們看到了一個如何使用filter()方法處理流的示例。我們還探討了一些處理異常的替代方法。

與往常一樣,完整的代碼可以在GitHub上找到