Bir önceki yazıda Java 8 ile gelen yeniliklerden olan default metodları, fonksiyonel arayüz kavramını, lambda ifadelerini ve metod referansı konusundan bahsetmiştim. Bu yazıda ise lambda ifadelerinde kullanmak üzere Java tarafından hazırlanmış yardımcı fonksiyonel arayüzlerden bahsedeceğim.
Yardımcı Fonksiyonel Arayüzler
Farklı tiplerdeki lambda ifadelerine temel oluşturmak için java.util.function paketi altında fonksiyonel arayüzler bulunmaktadır. Bunları 4 kategoriye ayırabiliriz.
- Consumer : Paremetre alıp işlem yapar ve geriye sonuç döndürmez.
- void accept(T t);
- Predicate: Parametre alır ve şarta bağlı olarak boolean sonuç döndürür.
- boolean test(T t);
- Supplier: Hiç parametre almaz ancak T tipinde değer döndürür.
- T get();
- Function: Parametre alır, işler ve geriye bir sonuç üretir.
- R apply(T t);
1. Consumer Arayüzü
Consumer yani türkçesi tüketici olan bu arayüz, jenerik olan T tipinde (yani isteğe göre herhangi bir Java tipi alabilir) bir parametre alan ve aynı zamanda geriye sonuç döndürmeyen bir metoda sahiptir.
Consumer tek bir soyut metoda sahip olduğundan dolayı funcitonal interface’dir. Temel olarak yaptığı iş kendisine verilen lambda ifadesini yerine getirmektir. Deyim yerindeyse bu işi tüketmektedir.
Basit bir örnekle başlayalım;
Daha kapsamlı bir örnekle, Consumer arayüzü içerisinde default olarak tanımlanmış andThen() metodununun kullanılışını görelim. Bu metod 2 Consumer’ı birbirine zincirleyerek accept() metodu çağrıldığında sıralı olarak çalışabilmelerini sağlar.
Consumer arayüzünü kullanırken jenerik tip kullanıyorduk, ancak primitive tip kullanmak istersek Java bizim için yardımcı arayüzleri hazırlamış. Bunlar;
- IntConsumer: Parametre olarak int değer alır.
- LongConsumer: Parametre olarak long değer alır.
- DoubleConsumer: Parametre olarak double değer alır.
- BiConsumer: T ve U tiplerinde iki parametre alır .
- ObjIntConsumer: T ve int tiplerinde iki parametre alır.
- ObjDoubleConsumer: T ve double tiplerinde iki parametre alır.
- ObjLongConsumer: T ve long tiplerinde iki parametre alır.
Not : Consumer arayüzü, Iterable arayüzünün içerisinde bulunan Collection’lar ile birlikte kullanılan forEach metodunda kullanılmaktadır.
2. Predicate Arayüzü
Türkçesi doğrulamak olan Predicate arayüzü, Consumer arayüzü gibi T tipinde bir girdi alır ve kendisine sunulan şartın sağlanıp sağlanmadığını kontrol ederek geriye “true ya da false” değer döner. Boolean dönüş değerine sahip bir işlev olarak düşünülebilir. Filtreleme ve gruplama gibi işlemlerde kullanılır.
Basit bir örnek yapalım.
Predicate arayüzü, test() metodu haricinde içerisinde 3 metod daha barındırır. Bu metodların yaptıkları iş şöyledir.
- and(): İki Predicate’i birleştirir ve mantıkta ki ve (&&) işlemine tabi tutar.
- or(): and() ile aynıdır ancak bu sefer mantıkta ki or işlemine tabi tutulur.
- negate(): Not ile aynı işlevi görür. Sonuç neyse tersini geri döndürür.
Bu metodların kullanıldığı küçük bir örnek yapalım.
Predicate arayüzü aynı zamanda primitive tipte değerler alabilecek versiyonlarıda bulunmakta.
- BiPredicate: T ve U tiplerinde iki parametre alır boolean değer üretir.
- IntPredicate: Parametre olarak int değer alıp sonuç üretir.
- DoublePredicate: Parametre olarak double değer alıp sonuç üretir.
- LongPredicate: Parametre olarak long değer alıp sonuç üretir.
3. Supplier Arayüzü
Supplier kelimesinin türkçesine baktığımızda “ihtiyacı karşılayan, satıcı” anlamlarının olduğunu görüyoruz. Bu arayüz, Consumer arayüzünün tam tersini yapar. Yani girdi olarak bir şey almaz ancak geriye bir değer döndürür.
Mesela, Person adında bir classımızın olsun ve yalnızca name adında bir propertye sahip olduğunu düşünelim. Supplier arayüzü yardımıyla bu sınıftan bir nesne oluşturulım. Constructor’ına parametre olarak isim bilgisini verelim.
Primitive tipler ve boolean değer içinde yardımcı alt arayüzler bulunmaktadır.
- BooleanSupplier: Geriye boolean değer döndürür.
- IntSupplier: Geriye int değer döndürür.
- DoubleSupplier: Geriye double değer döndürür.
- LongSupplier: Geriye long değer döndürür.
4. Function Arayüzü
Function arayüzü, jenerik olarak T tipinde bir parametre alır, verilen işi yürütür ve ardından R tipinde bir değer döndürür.
Örnekler üzerinden anlatmaya çalışayım.
Function arayüzünün çeşitleri oldukça fazladır. Yukarıdaki örnekte BiFunction ve UnaryOperator’den bahsettim ancak dilerseniz buradan tüm Function içeren sınıfları bulabilir ve metodları inceleyebilirsiniz.
Yazımı burada sonlandırıyorum. Bir sonraki bölüm Stream API hakkında olacak. Diziler ve Collection’lar üzerinde çalışan ve mükemmel kabiliyetleri olan Stream API’nin detaylarına gireceğiz. 🚀
Umarım bu yazı işinize yaramıştır. Herkese iyi çalışmalar dilerim. 👨🏻💻
Kaynaklar
- https://medium.com/@metinalniacik/javada-predicate-functional-interface-bb502cc864a9
- https://dogukanhan.com/category/java/java-util-function/
- https://kodedu.com/java-8-ebook/
- http://eherrera.net/ocpj8-notes/04-lambda-built-in-functional-interfaces#use-the-built-in-interfaces
- https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
- https://www.baeldung.com/java-8-functional-interfaces