Java – voo filtreerimine Lambda-avaldistega PlatoBlockchain Data Intelligence. Vertikaalne otsing. Ai.

Java – filtreerige voog Lambda avaldistega

Java Streams tutvustati Java 8-s 2014. aastal, et tutvustada paljusõnalist Java funktsionaalse programmeerimise paradigmale. Java Streams paljastab palju paindlikke ja võimsaid funktsionaalseid toiminguid, et teostada kogumistöötlust ühe kihina.

Mõnel predikaadil põhinevate kogude filtreerimine jääb üheks kõige sagedamini kasutatavaks funktsionaalseks toiminguks ja seda saab teostada Predicate või kokkuvõtlikult – a Lambda väljendus.

Selles lühikeses juhendis vaatleme, kuidas saate Lambda väljenditega Java 8 voogu filtreerida.

Voogude filtreerimine Javas

Üldiselt mis tahes Stream saab filtreerida kaudu filter() meetod ja antud predikaat:

Stream filter(Predicate<? super T> predicate)

Voo iga elementi käivitatakse predikaadi vastu ja lisatakse väljundvoogu, kui predikaat tagastab true. Saate pakkuda a Predicate näide:

Predicate contains = s -> s.contains("_deprecated");
List results = stream.filter(contains).collect(Collectors.toList());

Või lihtsustage seda, esitades Lambda avaldise:

List results = stream.filter(s -> s.contains("_deprecated"))
                             .collect(Collectors.toList());

Või isegi ahendada Lambda avaldis a meetodi viide:


List results = stream.filter(String::isEmpty)
                             .collect(Collectors.toList());

Meetodiviidetega ei saa te argumente edastada, kuid saate määratleda meetodid filtreeritavas objektis ja kohandada neid hõlpsalt filtreeritavaks (nii kaua kui meetod ei aktsepteeri argumente ja tagastab boolean).

Pea meeles, et vood ei ole kogud – need on ojad kogudestja peate need tagasi koguma mis tahes kogusse, näiteks a List, Mapjne, et anda neile püsivus. Lisaks tehakse kõik toimingud ka vooelementidega kesktaseme or terminal:

  • Vahetoimingud tagastavad uue voo, milles on eelmisest toimingust tehtud muudatused
  • Terminali toimingud tagastavad andmetüübi ja on mõeldud voo töötlemise konveieri lõpetamiseks

filter() on kesktaseme ja see on ette nähtud aheldamiseks teiste vaheoperatsioonidega enne voo lõpetamist. Muudatuste (nt elementide endi muudatused või filtreeritud tulemused) säilitamiseks peate määrama saadud väljundvoog terminalitoimingu kaudu uuele võrdlusmuutujale.

Märge: Isegi paljude lambda-avaldiste aheldamisel ei pruugi õigete reavahetustega tekkida loetavuse probleeme.

Järgmistes näidetes töötame selle raamatute loendiga.

Book book1 = new Book("001", "Our Mathematical Universe", "Max Tegmark", 432, 2014);
Book book2 = new Book("002", "Life 3.0", "Max Tegmark", 280, 2017);
Book book3 = new Book("003", "Sapiens", "Yuval Noah Harari", 443, 2011);
        
List books = Arrays.asList(book1, book2, book3);

Filtrikogu funktsiooniga Stream.filter()

Filtreerime selle raamatukogu. Iga predikaat sobib – nii et näiteks filtreerime selle järgi, millistel raamatutel on üle 400 lehekülje:

List results = books.stream()
                          .filter(b -> b.getPageNumber() > 400)
                          .collect(Collectors.toList());

Tulemuseks on loend, mis sisaldab:

[
Book{id='001', name='Our Mathematical Universe', author='Max Tegmark', pageNumber=432, publishedYear=2014}, 
Book{id='003', name='Sapiens', author='Yuval Noah Harari', pageNumber=443, publishedYear=2011}
]

Filtreerimisel on aheldamiseks väga kasulik meetod map(), mis võimaldab kaardistada objekte mõne muu väärtusega. Näiteks saame kaardistada iga raamatu selle nimega ja tagastada seega ainult nimed raamatutest, mis sobivad predikaadiga alates filter() helistama:

List results = books.stream()
                            .filter(b -> b.getPageNumber() > 400)
                            .map(Book::getName)
                            .collect(Collectors.toList());

Selle tulemuseks on stringide loend:

[Our Mathematical Universe, Sapiens]

Filtrikogu mitmel predikaadil funktsiooniga Stream.filter()

Tavaliselt soovime kogusid filtreerida rohkem kui ühe kriteeriumi alusel. Seda saab teha mitme aheldamisega filter() kõned or kasutades lühise predikaati, mis kontrollib kahte tingimust ühes filter() helistama.

 List results = books.stream()
                    .filter(b -> b.getPageNumber() > 400 && b.getName().length() > 10)
                    .collect(Collectors.toList());
                    


 List results2 = books.stream()
                    .filter(b -> b.getPageNumber() > 400)
                    .filter(b -> b.getName().length() > 10)
                    .collect(Collectors.toList());

Tutvuge meie praktilise ja praktilise Giti õppimise juhendiga, mis sisaldab parimaid tavasid, tööstusharus aktsepteeritud standardeid ja kaasas olevat petulehte. Lõpetage Giti käskude guugeldamine ja tegelikult õppima seda!

Mitme kriteeriumi kasutamisel võivad lambda-kõned veidi venida. Sel hetkel võib nende eraldamine eraldiseisvate predikaatidena pakkuda suuremat selgust. Samas, milline lähenemine on kiirem?

Üks keerukas seisukorras filter või mitu filtrit?

See sõltub teie riistvarast, teie kogu suurusest ja sellest, kas kasutate paralleelseid vooge või mitte. Üldiselt – üks keeruka tingimusega filter ületab mitut lihtsamate tingimustega filtrit (väikesed kuni keskmised kogud) või toimib samal tasemel (väga suured kogud). Kui teie tingimused on liiga pikad, võite saada kasu nende jagamisest mitme peale filter() nõuab paremat loetavust, kuna jõudlus on väga sarnane.

Parim valik on proovida mõlemat, pange tähele jõudlust sihtseadeja kohandage oma strateegiat vastavalt.

GitHubi kasutaja volkodavs tegi läbilasketoimingute/s filtreerimise võrdlusuuringu ja hostis tulemused saidil "javafiltrid-etalonid" hoidla. Tulemused on kokku võetud informatiivses tabelis:

See näitab selget tulude vähenemist suuremate kogude puhul, kusjuures mõlemad lähenemisviisid toimivad ligikaudu samal tasemel. Rööpvoogudest on suuremate kogumahtude korral märkimisväärselt kasu, kuid väiksemate suuruste puhul (alla ~10 XNUMX elementi) väheneb jõudlus. Väärib märkimist, et paralleelsed vood säilitasid oma läbilaskevõime palju paremini kui mitteparalleelsed vood, muutes need sisendiks oluliselt vastupidavamaks.

Ajatempel:

Veel alates Stackabus