# Java 8 Features ## Lambda İfadeleri JDK 8 ile dile eklenen lambda ifadeleri Javaâyı temelden etkilemiÅtir. Bir lambda ifadesi, en basit tanımıyla, isimsiz (anonim) bir metottur. Fakat bu metotları tanımlayabilmek için **fonksiyonel arayüz** (functional interface) oluÅturmak gerekir. Lambda ifadelerini daha iyi anlayabilmek için, fonksiyonel arayüzleri anlatmadan önce **anonim sınıflardan** (anonymous class) bahsedelim. ## Anonim Sınıflar Bir arayüz veya soyut sınıf üzerinden tanımlanan ve ismi olmayan sınıflara anonim sınıf denir. Bu sınıflar oluÅturuldukları anda kullanılırlar. Anonim sınıfların bir örneÄini alamazsınız; çünkü isimleri yoktur. Åimdi anonim sınıfları anlayabilmek için bir örnek yapalım. Ãncelikle bir arayüz tanımlayalım: ```java public interface Operation { int operate(int x, int y); } ``` **_Operation_** isminde bir arayüz tanımladık ve içine **operate()** adında bir metot yazdık. Bu metot int türünde iki sayıyı parametre olarak alır, bu sayılar üzerinde bir iÅlem yapar ve sonucu yine int türünde döndürür. Åimdi bu arayüzü kullanan bir metot yazalım: ```java public class Math { public static int operateTwoNumbers(int x, int y, Operation operation) { return operation.operate(x, y); } } ``` _Math_ adında bir sınıf tanımladık ve bu sınıf içinde statik **_operateTwoNumbers()_** metodunu yazdık. Bu metot int türünde iki sayıyı parametre alıyor ve bu sayılar üzerinde bir iÅlem yapıyor; fakat bu iÅlemin nasıl yapılacaÄını yine parametre olarak aldıÄımız **_Operation_** türündeki nesneden öÄreniyoruz. Åimdi, iki sayıyı toplayan bir Operation sınıfı yazalım: ```java public class AdditionOperation implements Operation { @Override public int operate(int x, int y) { return x + y; } } ``` Åimdi aÅaÄıdaki iÅlemi gerçekleÅtirebiliriz: ```java int result = Math.operateTwoNumbers(5, 10, new AdditionOperation()); System.out.println(result); ``` Bu kodu çalıÅtırdıÄınızda konsola 15 yazar; çünkü **_AdditionOperation_** sınıfı toplama iÅlemi yapmaktadır. Fakat burada Åunu düÅünelim: diyelim ki, bu metodu sadece bir kez kullandık. Sadece bir kez kullandıÄımız bu metot için **_AdditionOperation_** adında bir sınıf yazmamıza gerek var mıdır? Bunun yerine anonim sınıfları kullanabilirdik. Åimdi yukarıdaki kodu anonim sınıf kullanarak tekrar yazalım: ```java int result = Math.operateTwoNumbers(5, 10, new Operation() { @Override public int operate(int x, int y) { return x + y; } }); System.out.println(result); ``` Kalın olarak belirttiÄimiz kod anonim sınıf kodudur. GördüÄünüz gibi, new deyimini kullanarak **_Operation_** türünde bir nesne oluÅturduk; fakat bildiÄiniz gibi, new deyimini arayüzler üzerinde kullanamayız, yalnızca sınıflar üzerinde kullanabiliriz. Burada da new deyimini kullanarak bir sınıf oluÅturduk; fakat bu sınıfın bir ismi yoktur. Bu sınıfla ilgili bildiÄimiz tek Åey, **_Operation_** arayüzünü uyguladıÄıdır, dolayısıyla **_operate()_** metodunu yazmak zorundadır. Anonim sınıflar, yukarıda da gördüÄümüz gibi, bir arayüz veya soyut sınıf üzerinden oluÅturulan isimsiz sınıflardır. Bu sayede, bir daha hiçbir zaman kullanmayacaÄımız **_AdditionOperation_** sınıfını yazmamıza gerek kalmaz. Lambda ifadeleri, anonim sınıf kullanarak yazdıÄımız kodları daha kısa yazmamıza imkân tanır. Lambda ifadelerini kullanarak, yukarıda yazdıÄımız kodu aÅaÄıdaki gibi tek satırda da yazabiliriz: ```java int result = Math.operateTwoNumbers(5, 10, (x, y) -> x + y); System.out.println(result); ``` Kalın olarak belirttiÄimiz kod bir lambda ifadesidir. GördüÄünüz gibi, anonim sınıf yerine lambda ifadesi kullandıÄımız zaman kodu tek satıra indirgedik. Åimdi, lambda ifadelerini daha ayrıntılı incelemeden önce, fonksiyonel arayüzlerden bahsedelim. ## Fonksiyonel Arayüzler (Functional Interfaces) Anonim sınıfların isimsiz sınıflar olduÄunu belirtmiÅtik. İsimsiz bile olsalar, sınıfın yapısını belirleyebilmek için bir arayüze ihtiyaç duyarız. Lambda ifadelerinin de isimsiz metotlar olduÄunu söylemiÅtik; aynı Åekilde, isimsiz olsa bile bir metodun yapısını belirlemek gerekir. Bunu fonksiyonel arayüzleri kullanarak yaparız. İçinde en fazla 1 tane soyut metot bulunan arayüzlere fonksiyonel arayüz denir. Fonksiyonel arayüzleri lambda ifadelerini tanımlayabilmek için kullanırız. EÄer bir arayüzde birden fazla soyut metot varsa, bu arayüz ile lambda ifadesi tanımlayamayız; çünkü Java çalıÅma ortamı hangi metodu kullanarak lambda ifadesi yazdıÄımızı kestiremez. ÃrneÄin, aÅaÄıdaki 3 arayüzü inceleyelim: ```java interface MyInterface1 { void myMethod1(); } interface MyInterface2 { void myMethod2(); default Date now() { return new Date(); } } interface MyInterface3 { int myMethod3(); boolean myMethod4(double myParam1, int myParam2); } ``` **_MyInterface1_** ve **_MyInterface2_** arayüzleri fonksiyonel arayüzdür; çünkü bir tane soyut metot tanımlamıÅlardır. **_MyInterface3_** ise fonksiyonel arayüz deÄildir; çünkü birden fazla soyut metot tanımlamıÅtır. Bunun anlamı Åudur: **_MyInterface1_** ve **_MyInterface2_** arayüzlerini lambda ifadesi oluÅturmak için kullanabiliriz.