Java'da fonksiyonel programlama, lambda ifadeleri ve fonksiyonel arayüzlerin (Java 8'den itibaren) ortaya çıkmasıyla gelişti.
Konunun Tarihi
Java 8'den önce tüm arayüzler soyut metotların bir kümesi olarak tanımlanıyordu ve paradigma OOP'ye odaklanmıştı. Fonksiyonel arayüzler ve lambda ifadeleri ile daha kısa kod yazma ve FP ilkelerine uyma imkanı doğdu, bu da kodun okunabilirliğini ve ifadeliğini artırdı.
Sorun
Olayları, koleksiyonları veya asenkron mantığı işleyen kod fazla gelmekteydi: ayrı sınıflar veya anonim iç sınıflar oluşturmak gerekiyordu. Bu, kodun bakımını ve ölçeklenmesini zorlaştırıyordu.
Çözüm
Fonksiyonel arayüz, sadece bir tane soyut metod içeren bir arayüzdür. Lambda ifadesi için hedef olarak kullanılabilir. Standart kütüphanede Function<T, R>, Predicate<T>, Supplier<T>, Consumer<T> gibi tipik fonksiyonel arayüzler ortaya çıktı ve kendi arayüzlerinizi oluşturma imkanı sağlandı.
Kod örneği:
import java.util.function.Function; public class FunctionalExample { public static void main(String[] args) { // Standard fonksiyonel arayüz Function Function<String, Integer> stringLength = s -> s.length(); System.out.println(stringLength.apply("Java")); // 4 olarak yazdırır } }
Anahtar özellikler:
Birden fazla soyut metot içeren bir arayüz fonksiyonel arayüz olarak tanımlanabilir mi, eğer diğer metotların varsayılan bir uygulanımı veya statikse?
Hayır, fonksiyonel arayüz sadece bir soyut metot içerebilir. Varsayılan metot (default) veya statik metot bulundurulması mümkündür.
Fonksiyonel bir arayüz başka bir arayüzden birden fazla soyut metot ile miras alınabilir mi?
Hayır, eğer nihai arayüz birden fazla soyut metoda sahip olursa, fonksiyonel olmaktan çıkar ve lambda ifadesi için kullanılamaz.
Java'daki fonksiyonel arayüz ile diğer dillere, örneğin C#'daki SAM arayüzleri arasındaki fark nedir?
Java'da SAM arayüzleri için doğrudan bir anahtar kelime yoktur, @FunctionalInterface notasyonu ile tanımlanmadan önce. C#'da ise delegate kesin bir imza tanımlar, Java'da ise sadece bir soyut metot ve isteğe bağlı bir notasyon yeterlidir.
@FunctionalInterface notasyonunu unutmak - derleyici arayüz fonksiyonel olmaktan çıkarsa hemen hata vermiyor.Büyük bir projede lambda ifadelerini her yerde kullanmaya karar verdiler, hatta varlıkların veri sunduğu, iş mantığı ile doğrudan ilişkisi olmayan yerlerde bile. Sonuç olarak karmaşık mantık izlenmesi zor hale geldi, lambdalar kodun niyetini maskeledi ve hata ayıklama zorlaştı.
Artılar:
Eksiler:
Başka bir projede, hangi arayüzlerin FP için uygun olduğunu dikkatlice analiz ettiler. Koleksiyonlar ve olayları işlemek için Predicate, Function ve kendi arayüzlerini kullandılar. Varlıklar ve veri depolama için FP kullanılmadı.
Artılar:
Eksiler: