RetroLambda – Her yer lambda Her yerde lambda

Açıkçası uzun süre Java 6  kullanan biri olarak, Java 7 bana hiç cazip gelmemiÅŸti. Genelde enterprise düzeyde uygulamalar yazdığımdan ve bunu yaparken de spring kullandığımdan çok bir artısını görmedim. Özellikle multi-thread uygulamalar geliÅŸtiriyorsanız bir çok yenilik getiriyor Java 7 ama bu yeniliklerin hiç biri Java 8’deki kadar uygulamanızı nasıl geliÅŸtirdiÄŸinizi etkilemiyor. Bir Stream API ya da Lambda ifadeleri kadar insanı heyecanlandırmıyorda.

Her ne kadar Java 8 beni heyecanlandırsa da ne yazık ki geliÅŸtirdiÄŸim projelerde daha Java 8 kullanma imkanına sahip olamadım. Åžu anda geliÅŸtirmekte olduÄŸum proje Java 7 ile geliÅŸtirilirken, bundan önceki projem Java 6 ile geliÅŸtiriliyordu. Baktığınız zaman ikisi de miladını doldurdu. Her ikisinede (Java 7 ve Java 6) Oracle artık destek vermediÄŸini duyurdu. Bunun çeÅŸitli sebepleri var tabi. Heralde bu sebeplerden en önemlisi, Java’nın tam anlamıyla geriye dönük desteÄŸi vermiyor oluÅŸudur. Her bir yeni versiyondan sonra, Oracle, bir de geriye dönük desteklenmeyen ya da farklı davranan yerlerin listesini yayınlar. ÖrneÄŸin Java 7 ve Java 6 arasındaki tutarsızlıklara ya da Java 8 ve Java 7 arasındaki tutarsızlıklara bakabilirsiniz. Her ne kadar bu tutarsızlıklara denk gelmeniz pek olası gözükmese de büyük ölçekli kurumsal bir uygulamada siz ya da sizin kullandığınız bir kütüphane bu farklılıkları tutturabiliyor.java_lambda

Lambda ifadelerini ya da Stream API’nı kullanmamanız için sadece bu tutarsızlıklara denk gelmeniz gerekmiyor. Bir ÅŸirket politikasına da denk gelebilirsiniz ki bence bu çok daha büyük bir sorun. Bu sorunlar sadece sizden, projenizden ya da ÅŸirketinizden kaynaklı da olmayabilir. Android uygulaması geliÅŸtirdiÄŸinizi düşünün. Andorid uygulaması geliÅŸtirirken en çok Java 7 kullanabiliyorsunuz onu da anca KitKat ve üzeri için kullanabiliyorsunuz.

İşte tam bu noktada RetroLambda oyuna dahil oluyor. RatroLambda sizin için, Java8 lambda ifadelerinizi “backport” ediyor. Siz yine Java8’de geliÅŸtiriyorsunuz fakat kodunuzu, sorunsuz bir ÅŸekilde Java 7 ya da Java 6 üzerinde hatta android üzerinde çalıştırabiliyorsunuz. RetroLambda temel olarak java byte kodları ile oynuyor ve sizi Java8 bağımlılıklarından kurtarıyor. Ben detaylı olarak bunu nasıl yaptıklarına deÄŸinmeyeceÄŸim. Ama araÅŸtırırsanız bu çoÄŸu yere farklı uzunluklarda anlatmışlar. Benim anlatacağım, javada bunu nasıl kullanabileceÄŸiniz. Bir iki cümleyle de android üzerinde nasıl kullanabileceÄŸinizi anlatacağım.

Peki Lambda Nedir?

RetroLambda’ya geçmeden önce lambda ifadelerinin ne olduÄŸuna ve bizi nelerden kurtardığına kısaca deÄŸinmek itiyorum. EÄŸer daha önce Google Guava ya da RxJava benzeri, daha fonksiyonel programlamaya yönelik araçlar kullandıysanız, bir çok “anoynymous” sınıf kullanmışsınızdır. Hani ÅŸu bir ya da daha fazla methodtan oluÅŸan, isimsiz olarak, satır içinde tanımladığımız sınıflar var ya iÅŸte onları kastediyorum. Lambda ifadeleri temelde bizi bu sınıflardan kurtarıyor. Bir “syctactic sugar” olarak düşünebilirsiniz. Özellikle fonksiyonel programlama dillerinde bir hayli kullanılan yapılar bunlar. Bir çok genel amaca yönelik OO dillerde de bu zaten destekleniyor. Bakmayın java’ya biraz geç geldi. Tabi bu yapı için bir diÄŸer ihtiyacını olan ÅŸey de fonksiyonları parametre olarak geçmeniz. Ama okadar detayına girmeyeceÄŸim. Biraz daha görselleÅŸtirmek adına, Guava ile öncesi ve sonrası ÅŸeklinde kod bloklarımıza bakalım.

Örneğin elimizde bir listede User nesneleri olsun.

Bizse bu liste üzerinde kullanıcı adına göre arama yapıp, verdiğimiz parametre ile başlayan sonuçları dönelim. Bunu Guavasız ve Java 8 öncesinde lamdasız yapmak istersek aşağıdaki gibi bir for yazmamız lazım.

Lamdasız ve Guavasız

Gördüğünüz gibi çok güzel olmayan bir kod elde etmiş olduk. Bunu guava ile yapmak istersek daha güzel fakat yeterince güzel olmayan bir kod elde etmiş oluyoruz.

Lamdasız fakat Guavalı

Burada Predicate ile bir “anoynymous” sınıf oluÅŸturmuÅŸ olduk. Bence daha güzel oldu. Zaten Java 6 ya da Java 7 projelerimde sıkça kullanıyorum bu kütüphaneyi. Java 8 projesi geliÅŸtirdiÄŸimde Stream API’dan dolayı ihtiyacım olacağını sanmıyorum.

Evet şimdi de bunu Lambda ifadeleri ile nasıl yazacağımıza bakalım.

Lambdalı

Gördüğünüz gibi çok daha basit bir hale geldi. Hatta okadar basit ki ayrı bir methoda çıkmaya bile gerek yok. İşte biz bu ifadeleri Java 7 ve Andorid sistemlerde nasıl kullanabileceğimize bakacağız.

RetroLambda

RetroLambday’ı projenize entegre etmenizin farklı yolları bulunuyor. Standalone uygulamanıza javaagent olarak vereiblirsiniz ya da build döngünüze oturtabilirsiniz. Build döngüsüne rahat oturtabilmeniz için popüler build araçarını da destekliyor. Ben normal java projelerinde ağırlıklı Maven kullandığımdan maven ile ne ÅŸekilde yapacağınıza deÄŸineceÄŸim.

Maven

Maven ile projenizi build ederken sadece aÅŸağıdaki plugin’i eklemeniz yeterli. Plugin sizin için lambda ile oluÅŸan sınıfların yerine, Java7 (ya da target versiyonunuz neyse) uyumlu sınıfları koyacaktır.

pom.xml

Burada dikkat etmeniz gereken noktalar aşağıdaki gibidir.

  • GeliÅŸtirirken Java 8 kullandığımız için, “compile” plugin’inde kaynak kodumuzu ve hedefimizi Java 8 olarak veriyoruz.
  • Daha sonra retrolambda pluginini ekliyoruz. RetroLambda’da gerçekte kodumuzu çalıştırmayı hedeflediÄŸimiz ortamı giriyoruz. Biz Java 7’yi hedef aldığımızdan buraya 1.7 giriyoruz.
  • BaÅŸka bir bağımlılık vermemize gerek yok. Örneklerde kullandığımız guava kütüphanesini ekliyoruz sadece. RetroLambda için ek bir kütüphaneye ihtiyacımız yok.

Şimdi ise örnek kodumuza bakalım. Maven projemize App.java sınıfını ekliyoruz ve içeriğini aşağıdaki gibi yapıyoruz.

App.java

Bu kodumuzu IDE içerisinden yani Java 8 ile çalıştırdığımızda aşağıdaki çıktıyı alıyoruz.

Java8-Output

Daha sonra projemizi, maven shade plugin’i ile çalıştırılabilir JAR haline getiriyoruz ve Java 7 ortamında çalıştırıyoruz. Java 7 otamında ise aynı çıktıyı alıyoruz.

Java7-Output

Åžimdi ise benzer iÅŸlemi kısaca andorid’te nasıl yapacağımıza bakalım.

Andorid

RetroLambda tüm popüler ortamları desteklediÄŸinden yapmanız gereken tek ÅŸey gradle build döngünüze retrolambda’yı eklemek. Ne yazıkki Java 7 de olduÄŸu kadar rahat bir ÅŸekilde eklenemeyecek. Ama mantık olarak aynı ÅŸeyleri yapacağız. Önce kaynak kodlarımızın Java 8 içerdiÄŸini belirteceÄŸiz. Sonra eklentiyi tanımlayıp ilgili ayarlarını yapacağız. Tüm deÄŸiÅŸikliklerimizi build.gradle üzerinde yapacağız.

Kaynak Kodu Versiyonlarının Tanımlanması

Kaynak kodu versiyonlarımızı tanımladığımıza göre şimdi build döngüsüne ilgili eklentimizi kayıt edelim. Bunun için aşağıdaki eklemeleri yapıyoruz.

Build Döngüsünün Kurulması

Son olarak ayarlarımızı yapalım. Android için geliştirme yaparken JAVA8_HOME ve JAVA6_HOME sistem değişkenlerinin tanımlı olması gerekiyor. Bu değişkenlerimizi ayarlarımızda kullanacağız.

Ayarların Yapılması

Sonoctobiwan

Umarım RetroLamba’nın neler getirdiÄŸini ve nasıl kullanabileceÄŸinizi açıklayabilmiÅŸimdir. Java’da geliÅŸtirilmiÅŸ örneÄŸin kaynak kodlarını aÅŸağıdaki adresten indirebilirsiniz.

Git: https://github.com/bhdrkn/Java-Examples/tree/master/retrolambda-sample

End of Line