Java-stroomfilter met Lambda-expressie

1. Inleiding

In deze korte tutorial gaan we het gebruik van de Stream.filter () methode als we ermee werken Streams in Java.

We zullen bekijken hoe u het kunt gebruiken en hoe u speciale gevallen met aangevinkte uitzonderingen kunt afhandelen.

2. Met behulp van Stream.filter ()

De filter() methode is een tussenliggende bewerking van de Stroom interface waarmee we elementen van een stream kunnen filteren die overeenkomen met een gegeven Predikaat:

Stroomfilter (predikaatpredikaat)

Laten we een Klant klasse:

openbare klasse Klant {privé Stringnaam; privé int punten; // Constructor en standaard getters}

Laten we daarnaast een verzameling klanten maken:

Klant john = nieuwe klant ("Jan P.", 15); Klant sarah = nieuwe klant ("Sarah M.", 200); Klant charles = nieuwe klant ("Charles B.", 150); Customer mary = nieuwe klant ("Mary T.", 1); Lijst met klanten = Arrays.asList (john, sarah, charles, mary);

2.1. Verzamelingen filteren

Een veelvoorkomend geval van het filter() methode is het verwerken van collecties.

Laten we een lijst maken van klanten met meer dan 100 punten. Om dat te doen, kunnen we een lambda-uitdrukking gebruiken:

Lijst customersWithMoreThan100Points = klanten .stream () .filter (c -> c.getPoints ()> 100) .collect (Collectors.toList ());

We kunnen ook een methodeverwijzing gebruiken, wat een afkorting is voor een lambda-uitdrukking:

Lijst customersWithMoreThan100Points = klanten .stream () .filter (Klant :: hasOverHundredPoints) .collect (Collectors.toList ());

In dit geval hebben we het hasOverHundredPoints methode naar onze Klant klasse:

openbare boolean hasOverHundredPoints () {retourneer this.points> 100; }

In beide gevallen krijgen we hetzelfde resultaat:

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

2.2. Verzamelingen met meerdere criteria filteren

Verder kunnen we meerdere voorwaarden gebruiken bij filter(). We kunnen bijvoorbeeld filteren op punten en naam:

Lijst charlesWithMoreThan100Points = klanten .stream () .filter (c -> c.getPoints ()> 100 && c.getName (). StartsWith ("Charles")) .collect (Collectors.toList ()); assertThat (charlesWithMoreThan100Points) .hasSize (1); assertThat (charlesWithMoreThan100Points) .contains (charles);

3. Uitzonderingen afhandelen

Tot nu toe hebben we het filter gebruikt met predikaten die geen uitzondering genereren. Inderdaad, de functionele interfaces in Java declareren geen aangevinkte of niet-aangevinkte uitzonderingen.

Vervolgens gaan we enkele verschillende manieren laten zien om met uitzonderingen in lambda-expressies om te gaan.

3.1. Met behulp van een aangepaste wrapper

Eerst beginnen we met het toevoegen van een profilePhotoUrl naar onze Klant:

privé String profilePhotoUrl;

Laten we bovendien een simpele hasValidProfilePhoto () methode om de beschikbaarheid van het profiel te controleren:

openbare boolean hasValidProfilePhoto () gooit IOException {URL url = nieuwe URL (this.profilePhotoUrl); HttpsURLConnection-verbinding = (HttpsURLConnection) url.openConnection (); return connection.getResponseCode () == HttpURLConnection.HTTP_OK; }

We kunnen zien dat de hasValidProfilePhoto () methode gooit een IOException. Als we nu proberen de klanten met deze methode te filteren:

Lijst customersWithValidProfilePhoto = klanten .stream () .filter (Klant :: hasValidProfilePhoto) .collect (Collectors.toList ());

We zien de volgende foutmelding:

Incompatibele gegooide typen java.io.IOException in functionele expressie

Om ermee om te gaan, is een van de alternatieven die we kunnen gebruiken het omwikkelen met een try-catch-blok:

List customersWithValidProfilePhoto = customers .stream () .filter (c -> {probeer {return c.hasValidProfilePhoto ();} catch (IOException e) {// handle exception} return false;}) .collect (Collectors.toList ()) ;

Als we een uitzondering van ons predikaat moeten gooien, kunnen we deze in een niet-aangevinkte uitzondering plaatsen, zoals RuntimeException.

3.2. ThrowingFunction gebruiken

Als alternatief kunnen we de ThrowingFunction-bibliotheek gebruiken.

ThrowingFunction is een open source-bibliotheek waarmee we gecontroleerde uitzonderingen in functionele Java-interfaces kunnen afhandelen.

Laten we beginnen met het toevoegen van de gooien-functie afhankelijkheid van onze pom:

 pl.touk werpfunctie 1.3 

Om uitzonderingen in predikaten af ​​te handelen, biedt deze bibliotheek ons ​​de Gooien Predicaat klasse, die de niet aangevinkt () methode om aangevinkte uitzonderingen te verpakken.

Laten we het in actie zien:

Lijst customersWithValidProfilePhoto = klanten .stream () .filter (ThrowingPredicate.unchecked (Customer :: hasValidProfilePhoto)) .collect (Collectors.toList ());

4. Conclusie

In dit artikel hebben we een voorbeeld gezien van het gebruik van de filter() methode om streams te verwerken. We hebben ook enkele alternatieven onderzocht om met uitzonderingen om te gaan.

Zoals altijd is de volledige code beschikbaar op GitHub.