Java - Lambda İfadeleri ile Bir Akışı Filtreleyin PlatoBlockchain Veri Zekası. Dikey Arama. Ai.

Java – Bir Akışı Lambda İfadeleriyle Filtreleyin

Java Akışları, ayrıntılı Java'yı bir İşlevsel Programlama paradigmasıyla tanıştırmak amacıyla 8'te Java 2014'de tamamen tanıtıldı. Java Akışları, tek satırda toplama işlemini gerçekleştirmek için birçok esnek ve güçlü işlevsel işlemi ortaya çıkarır.

Bazı yüklemlere dayalı koleksiyonları filtrelemek, en yaygın olarak kullanılan işlevsel işlemlerden biri olmaya devam etmektedir ve bir Predicate veya daha kısaca - bir Lambda İfadesi.

Bu kısa kılavuzda, Lambda İfadeleri ile bir Java 8 Akışını nasıl filtreleyebileceğinize bir göz atacağız.

Java'da Akışları Filtreleme

Genel olarak, herhangi Stream aracılığıyla filtrelenebilir. filter() yöntem ve belirli bir yüklem:

Stream filter(Predicate<? super T> predicate)

Akıştaki her öğe, yüklemeye karşı çalıştırılır ve yüklem geri dönerse çıkış akışına eklenir. true. bir tedarik edebilirsiniz Predicate örnek:

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

Veya bir Lambda İfadesi sağlayarak basitleştirin:

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

Hatta Lambda İfadesini bir yöntem referansı:


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

Yöntem referanslarıyla argümanları iletemezsiniz, ancak filtrelediğiniz nesnede yöntemleri tanımlayabilir ve bunları kolayca filtrelenebilir olacak şekilde uyarlayabilirsiniz (yöntem argümanları kabul etmediği ve bir boolean).

Unutmayın akışlar koleksiyon değildir - onlar akışlar koleksiyonlarınve bunları herhangi bir koleksiyonda toplamanız gerekir. List, Map, vb kalıcılık kazandırmak için. Ek olarak, akış öğelerinde yapılan tüm işlemler ya ara or terminal:

  • Ara işlemler, önceki işlemdeki değişikliklerle yeni bir akış döndürür
  • Terminal işlemleri bir veri türü döndürür ve bir akışta bir işlem hattını sonlandırmayı amaçlar.

filter() bir ara işlemdir ve akış sonlandırılmadan önce diğer ara işlemlerle zincirlenmesi amaçlanmıştır. Herhangi bir değişikliği (öğelerin kendisinde veya filtrelenmiş sonuçlarda yapılan değişiklikler gibi) kalıcı kılmak için sonucu atamanız gerekir. çıkış akışı bir terminal işlemi aracılığıyla yeni bir referans değişkenine.

Not: Birçok lambda ifadesini zincirlerken bile, uygun satır sonlarıyla okunabilirlik sorunlarıyla karşılaşmayabilirsiniz.

Aşağıdaki örneklerde, bu kitap listesiyle çalışacağız:

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);

Stream.filter() ile Filtre Toplama

Bu kitap koleksiyonunu filtreleyelim. Herhangi bir yüklem geçerli – örneğin hangi kitapların 400'den fazla sayfaya sahip olduğunu filtreleyelim:

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

Bu, aşağıdakileri içeren bir listeyle sonuçlanır:

[
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}
]

Filtreleme yaparken, zincirleme için gerçekten yararlı bir yöntem map()nesneleri başka bir değere eşlemenizi sağlayan . Örneğin, her kitabı adıyla eşleştirebilir ve böylece yalnızca isimleri yüklemine uyan kitapların filter() telefon etmek:

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

Bu, dizelerin bir listesiyle sonuçlanır:

[Our Mathematical Universe, Sapiens]

Stream.filter() ile Çoklu Tahminlerde Filtre Toplama

Genellikle koleksiyonları birden fazla kritere göre filtrelemek isteriz. Bu, birden fazla zincirleme ile yapılabilir. filter() aramalar or tek bir durumda iki koşulu kontrol eden bir kısa devre yüklemi kullanarak filter() aramak.

 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());

En iyi uygulamalar, endüstri tarafından kabul edilen standartlar ve dahil edilen hile sayfası ile Git'i öğrenmek için uygulamalı, pratik kılavuzumuza göz atın. Googling Git komutlarını durdurun ve aslında öğrenmek o!

Birden fazla kriter kullanıldığında – lambda çağrıları biraz uzayabilir. Bu noktada, bunları bağımsız yüklemler olarak çıkarmak daha fazla netlik sağlayabilir. Yine de, hangi yaklaşım daha hızlı?

Karmaşık Koşullu Tek Filtre veya Çoklu Filtreler?

Donanımınıza, koleksiyonunuzun ne kadar büyük olduğuna ve paralel akış kullanıp kullanmadığınıza bağlıdır. Genel olarak – karmaşık koşula sahip bir filtre, daha basit koşullara sahip (küçük ila orta koleksiyonlar) birden fazla filtreden daha iyi performans gösterecek veya aynı düzeyde performans gösterecektir (çok büyük koleksiyonlar). Koşullarınız çok uzunsa - bunları birden fazla yere dağıtmaktan yararlanabilirsiniz. filter() performans çok benzer olduğu için daha iyi okunabilirlik gerektirir.

En iyi seçim, her ikisini de denemektir, performansı not edin. hedef cihazve stratejinizi buna göre ayarlayın.

GitHub kullanıcısı volkodavlar çıktı işlemlerinde/işlemlerinde bir filtreleme kıyaslaması yaptı ve sonuçları “javafilters-kıyaslamaları” depo. Sonuçlar bilgilendirici bir tabloda özetlenmiştir:

Her iki yaklaşımın da aynı seviyede performans göstermesiyle, daha büyük koleksiyon boyutlarında net bir geri dönüş düşüşü olduğunu gösteriyor. Paralel akışlar, daha büyük toplama boyutlarında önemli ölçüde fayda sağlar, ancak daha küçük boyutlarda (~10k öğelerin altında) performansı engeller. Paralel akışların verimlerini paralel olmayan akışlardan çok daha iyi koruduğunu ve bu da onları giriş için önemli ölçüde daha sağlam hale getirdiğini belirtmekte fayda var.

Zaman Damgası:

Den fazla Yığın kötüye kullanımı