Upload
onurguney
View
44
Download
2
Embed Size (px)
DESCRIPTION
e
Citation preview
Java 8 EbookRahman Usta
iii
indekilernsz ......................................................................................................................... xi1. Lambda Expression nedir? Nasl kullanrm? ............................................................. 1
1.1. Lambda nedir? .............................................................................................. 11.2. Javascript ile Lambda Basit Giri ................................................................ 11.3. Lambda Java 8 ncesinde nasld? ................................................................ 21.4. Java 8 ve Lambda ifadeleri ............................................................................ 3
2. Lambda ifadeleri ve Fonksiyonel arayzler ................................................................ 52.1. Functional Interfaces ..................................................................................... 5
3. Tarih ve Saat ilemleri ............................................................................................. 93.1. LocalDate ..................................................................................................... 93.2. LocalTime ................................................................................................... 103.3. LocalDateTime ............................................................................................ 113.4. ZoneId ........................................................................................................ 123.5. ZonedDateTime ........................................................................................... 13
4. Consumer Arayz ................................................................................................. 154.1. Java 8 ncesi ............................................................................................. 154.2. Java 8 sonras ............................................................................................ 164.3. Lambda deyimleri aklldr ............................................................................ 164.4. Consumer arayz nerede kullanlyor? ........................................................ 174.5. Lambda deyimlerini Metod Referanslar ile kullanabiliriz. ................................ 17
5. Lambda rnekleri ................................................................................................... 195.1. Consumer Arayz ...................................................................................... 195.2. BiConsumer Arayz ................................................................................... 195.3. Function Arayz ........................................................................................ 205.4. UnaryOperator Arayz ............................................................................... 205.5. BiFunction Arayz ..................................................................................... 215.6. BinaryOperator Arayz ............................................................................... 215.7. Predicate Arayz ....................................................................................... 215.8. BiPredicate Arayz .................................................................................... 225.9. Supplier Arayz ......................................................................................... 22
6. Notasyonlar ve Tekrarl Notasyonlar ........................................................................ 256.1. Notasyonlar ve Alanlar ................................................................................ 276.2. Notasyonlara Eriim ..................................................................................... 286.3. Notasyonlarn Tekrarl Kullanlmas ............................................................... 29
7. Method Reference .................................................................................................. 317.1. Bir metodu referans vermek ......................................................................... 32
Java 8 Ebook
iv
8. Default Methods ..................................................................................................... 378.1. Varsaylan Metoda Giri ............................................................................... 378.2. Varsaylan metodlarda akma .................................................................... 398.3. Varsaylan metodlar ve Fonksiyonel arayzler ............................................... 418.4. Varsaylan metodlar ve JDK ......................................................................... 42
9. Stream API ............................................................................................................ 459.1. Stream nesnesi nasl elde edilir? .................................................................. 46
9.1.1. Collection API ile .............................................................................. 469.1.2. New I/O ile ....................................................................................... 479.1.3. IntStream, DoubleStream, LongStream ile .......................................... 48
9.2. Stream API rnekleri ................................................................................... 489.2.1. forEach ............................................................................................ 489.2.2. filter ................................................................................................. 499.2.3. distinct ............................................................................................. 499.2.4. sorted .............................................................................................. 509.2.5. limit .................................................................................................. 509.2.6. count ................................................................................................ 509.2.7. collect .............................................................................................. 519.2.8. map ................................................................................................. 529.2.9. reduce .............................................................................................. 539.2.10. map & reduce ................................................................................. 54
9.3. Parallel Stream ........................................................................................... 569.4. Lazy & Eager operasyonlar .......................................................................... 57
10. Java 8 ve JVM Dilleri ........................................................................................... 5910.1. JVM Dilleri ................................................................................................ 5910.2. Java Scripting API ..................................................................................... 6110.3. ScriptEngine .............................................................................................. 6110.4. Nashorn JavaScript Motoru ........................................................................ 62
11. Java 8 Optional Yenilii ........................................................................................ 6311.1. Optional Oluturmak .................................................................................. 6311.2. #ifPresent - Varsa yap, yoksa yapma .......................................................... 6411.3. #map - Dntrme ................................................................................... 6511.4. #filter - Filtreleme ...................................................................................... 6511.5. #orElse - Varsa al, yoksa bunu al ............................................................... 6511.6. #orElseGet - Varsa al, yoksa ret ............................................................... 6611.7. #orElseThrow - Varsa al, yoksa frlat .......................................................... 66
12. Java 8 Embedded ................................................................................................ 6912.1. JavaFX Extension ...................................................................................... 71
Java 8 Ebook
v
12.2. Nashorn Extension .................................................................................... 7212.3. Java 8 ME vs Java 8 Embedded ................................................................ 72
13. CompletableFuture ile Asenkron Programlama ....................................................... 7513.1. Syncronous vs. Asyncronous ..................................................................... 7513.2. CompletableFuture#allOf ............................................................................ 7713.3. CompletableFuture#anyOf .......................................................................... 7813.4. CompletableFuture#supplyAsync ................................................................ 7913.5. lk yol, join() metodu kullanmak ............................................................ 8013.6. kinci yol, thenAccept* metodu kullanmak .............................................. 8113.7. CompletableFuture#runAfterBoth* ............................................................... 8113.8. CompletableFuture#runAfterEither* ............................................................. 8213.9. CompletableFuture#handle* ....................................................................... 82
14. Java ME 8 Embedded ve Raspberry PI ................................................................. 8514.1. Java ME 8 ile Raspberry PI zerinde LED yakma ........................................ 8614.2. Donanmsal Gereksinimler ......................................................................... 86
14.2.1. Raspberry PI .................................................................................. 8614.2.2. Bread Board ................................................................................... 8614.2.3. SD Kart .......................................................................................... 8714.2.4. Adaptr .......................................................................................... 8714.2.5. Wifi adapter .................................................................................... 8714.2.6. Kablo, Led, GPIO Extension Board .................................................. 8814.2.7. HDMI Kablosu ................................................................................ 8914.2.8. Klavye ve Maus .............................................................................. 89
14.3. Yazlmsal Gereksinimler ............................................................................ 8914.4. Raspbian OS Kurulmas ............................................................................. 91
14.4.1. Devrenin Kurulmas ......................................................................... 9114.5. Java ME 8in Raspberry PIye Yklenmesi .................................................. 9314.6. Java MEnin altrlmas .......................................................................... 9514.7. Device Managera Rapberry PI Tantmak .................................................... 9514.8. Java ME 8 Embedded Projesinin Oluturulmas ........................................... 97
14.8.1. Adm 1 ........................................................................................... 9714.8.2. Adm 2 ........................................................................................... 9814.8.3. Adm 3 ........................................................................................... 98
14.9. Uygulamann Yazlmas ............................................................................. 9914.10. Projeye Aygt Tantmak ......................................................................... 10114.11. Uygulama zinlerini Tanmlamak .............................................................. 10214.12. Uygulamann altrlmas ..................................................................... 103
A. Bu kitap nasl yazld? .......................................................................................... 105
xi
nszJava 8 ve yeniliklerini ieren bu kitap ile, Java programlama dilinin en yeni zelliklerinirenebilirsiniz.
Java 8 Ebook kodcu.com1 'da Rahman Usta2 tarafndan kaleme alnan Java 8 yazlarniermektedir.
1 http://kodcu.com2 http://kodcu.com/author/rahmanusta/
1Blm 1. Lambda Expression nedir?Nasl kullanrm?Merhaba arkadalar;
Bugn sizlerle Java 8 (Project Lambda) ile Java ortamna katlan Lambda ifadelerinden(Lambda expression) bahsetmek istiyorum.
1.1. Lambda nedir?
Programlama dili erevesinde Lambda, anonim tekil grevler olarak deerlendirilebilir.Lambda deyimleri (Lambda fonksiyonlar da denebilir), referans verilebilir ve tekrar tekrarkullanlabilirdir. Genel kullanm asndan Lambda fonksiyonlar, dier bir fonksiyona argmanolarak iletilebilirdir. Bylece, bir tarafta tanmlanan i birimi, dier bir i biriminde koturulabilirolmaktadr. Burada dikkat ekilecek unsur, bir i biriminin dier bir uygulama birimine referansolarak eritirilebilirliidir.
1.2. Javascript ile Lambda Basit Giri
Javascript dilinde Array snfnn prototype alannda forEach isimli bir i birimi (fonksiyon)bulunmaktadr. forEach fonksiyonu, parametre olarak bir anonim Javascript fonksiyonunukabul etmektedir. forEach fonksiyonuna, parametre olarak tanmlanan anonim fonksiyon,forEach fonksiyonu ierisinde koturulmaktadr. Bu sayede i mant, dier fonksiyonapaslanm olmaktadr.
rnek 1:
var dizi = [1,2,3,4,5]; // Bir javascript dizisi
// Anonim fonksiyon her bir eleman ktlyor.dizi.forEach(function(e){ // (1) console.log("Eleman: ",e);});
Yukarda (1) numaral ksmdaki anonim fonksiyon yani lambda fonksiyonu, forEachmetodu ierisinde koturulmaktadr. forEach metodu ierisindeki benzer yaklam, kendifonksiyonumuz ile oluturalm.
Lambda Java 8ncesinde nasld?
2
var fonk= function(a,b,callback){ // Lambda fonksiyonu "callback" burada koturulur. return callback(a,b)*2; // (2)}
var result = fonk(2,3,function(a,b){ // (1) // Bu Lambda fonksiyonu 2 argman toplar. return a+b;});
console.log("Sonu ..: ",result); // Sonu : (2+3)*2 = 10
Tekrar ederek, Lambda fonksiyonlar iin referans verilebilir i birimleri denebilir. Bu yaklambir ok programlama dilinde farkl biimlerde yer alabilir, anlalabilirlik asndan ilk nceJavascript rnei vermeyi tercih ettim.
1.3. Lambda Java 8 ncesinde nasld?Lambda birimleri (referans verilebilir i birimleri), Java 8 evvelinde anonim snflar iletanmlanabilmekteydi. rnek 2nin benzeri Java 8 evvelinde nasl yazlyordu?
ncelikle bir i birimi tipi gerekli, bu i birimi 2 argman kabul etmeli ve bir deer dndrmelidir. mant anonim olarak tanmlanaca iin, abstract snflar veya arayzler kullanlabilir.
rnek 3
public interface Anonim{ public int call(int a, int b);}
Anonim arayz szlemesi, int trnden 2 deer alr ve bir int deer dndrr. Dikkatederseniz sadece szlemenin maddesi tanmland, i mant anonim olarak gelitiricitarafndan tanmlanacak.
public class LambdaApp {
public static void main(String[] args) {
LambdaApp app = new LambdaApp();
// rnek 2 (1) gibi
app.fonk(2, 3, new Anonim() {
Java 8 ve Lambda ifadeleri
3
@Override public int call(int a, int b) { return a + b; } });
}
// rnek 2 (2) gibipublic int fonk(int a, int b, Anonim anonim) {
return anonim.call(a, b) * 2; };
}
Anonim i birimi burada tanmlanyorAnonim i birimi burada koturuluyor
1.4. Java 8 ve Lambda ifadeleriLambdaApp snfnn (1) numaral ksmndaki anonim i birimi, Javascript dilindeki karlnagre u anda ok daha kompleks. 6 komut satr yer igal ediyor. Fakat bu fonksiyonun yapttek i var, 2 argman almak ve toplayp geri dndrmek. Bu anonim birimi sanyorum ubiimde temsil edebiliriz.
fn(a,b) -> (a+b);
Grld zere tek bir satrda ayn ii gren anonim i birimini yani lambda ifadesini yazdk.Ayn rnei imdi Java 8 Lambda deyimi ile yazalm.
public interface Anonim{ public int call(int a, int b);}
public class LambdaAppJava8 {
public int fonk(int a, int b, Anonim anonim) { return anonim.call(a, b) * 2;};
public static void main(String[] args) {
Java 8 ve Lambda ifadeleri
4
LambdaAppJava8 app = new LambdaAppJava8();
app.fonk(2, 3, (a, b) -> a + b); // Dikkat (1)}
}
Grld zere 6 satrlk anonim snf kullanmn, tek satra drm olduk.
Lambda ifadeleri, Java 8 versiyonunun en arpc yeniliklerinden biri. (Bkz. Project Lambda1 ).
Sizler de Java 8 kullanmak istiyorsanz https://jdk8.java.net/ adresinden sisteminizekurabilirsiniz.
Bol Javal gnler dilerim.
1 http://openjdk.java.net/projects/lambda/
5Blm 2. Lambda ifadeleri veFonksiyonel arayzlerMerhaba arkadalar;
Bugn sizlerle fonksiyonel arayzlerden ( Functional Interfaces ) ve Lambda ifadeleri(Lambda Expressions) ile olan ilikisinden basetmek istiyorum.
2.1. Functional InterfacesTek bir soyut metodu bulunan arayzlere fonksiyonel arayz denir. ki veya deil,yalnzca bir tane soyut metodu olmal. Peki neden 1 dersek sebebinin Lambda ifadelerinedayandn sylemek isterim.
rnein;
yle bir Lambda ifademiz olsun;
fn(x,y) -> 2*x + y
Bu Labmda deyimini rnein Javascript gibi bir dil ile temsil etmek isteseydik yle yazabilirdik;
function(x , y) {
return 2*x+y;
}
Peki fn(x,y) 2*x + y Lambda ifadesini Java programlama dilinde nasl yazabiliriz?
Java 8 gelitirilirken, gelitirim takm kendilerine bu soruyu sormu ve yant olarak fonksiyonelarayzler kullanarak ihtiyac karlamlar.
yle ki; Bir Lambda ifadesi, Java derleyicisi tarafndan, bir Java arayznn (tek bir soyutmetodu olmal) nesnel karlna (implementation) dntrlmektedir.
rnein, fn(x,y) 2*x + y Lambda ifadesi, aadaki fonksiyonel arayzedntrlebilirdir. nk fonksiyon x ve y adnda iki parametre almakta ve 2*x + y ile tek bir
Functional Interfaces
6
deer dndrmektedir. Tabi burada x ve y nin tipleri ne? dersek, herhangi bir matematikseltip olabilir. Biz burada sabit bir tip (int gibi) verebilir, veya jenerik tiplemeler de yapabiliriz. Fakatu anlk bununla yetinelim.
@FunctionalInterface // Opsiyonelinterface Foo{
int apply(int x, int y);
}
imdi bu Lamda ifadesini uygulamamzda kullanalm.
rnek 1:
Lambda ifadeleri atama srasnda kullanlabilir.
Foo foo = (x,y) -> (2*x+y);
int sonuc = foo.apply(3,4);
System.out.println("Sonu: "+sonuc); // kt: 10
// veya
Foo foo = (x, y) -> Math.pow(x,y);
int sonuc = foo.apply(3,2);
System.out.println("Sonu: "+sonuc); // kt: 3*3 = 9
rnek 2:
Lambda ifadeleri, metod parametrelerinde de tanmlanabilir.
class Bar{
public int calculate(Foo foo, int x, int y){ return foo.apply(x,y); }}
Bar bar = new Bar();
Functional Interfaces
7
int sonuc = bar.calculate( (x,y) -> (2*x+y) , 3, 4 );
System.out.println("Sonu: "+sonuc); // kt: 10
Java programlama dilinde fonksiyon ifadesi pek kullanlmaz, onun yerine metod ifadesikullanlr. Java metodlar tek bana birer eleman deildir, dier bir dil elemannn (snf,enum, interface ..) dahilinde tanmlanrlar. Javascript gibi dillerde ise fonksiyonlar tek banabirer elemandr, dier bir dil elemannn iinde olmak zorunluluu yoktur. Bu sebepleJava ortamnda, bir Lambda ifadesinden bir fonksiyona/metoda/i birimine dnm iinfonksiyonel arayzler kullanlmaktadr.
Tekrar grmek dileiyle..
8
9Blm 3. Tarih ve Saat ilemleriJava 8 ierisinde zaman temsili iin yeni bir Date-Time API gelitirildi. Java programlamadilinde zamansal ilemler iin JSR 310: Date and Time API artnamesi yer almaktadr. Java 8ile birlikte yeniden dzenlenen bu artname, yepyeni zellikler sunmaktadr. Yeni gelitirilenDate-Time APInin referans implementr ThreeTen projesidir.
Yeni Date-Time API ile kolay kullanm, anlalrlk, thread-safety gibi hususlarda iyiletirmelerkarmza kyor. Bu yeni API ye dair bileenler (snf, arayz, enum vs.) java.time paketialtnda yer almaktadr. imdi sizlerle java.time paketi ierisinde yer alan bileenler ile ilgilikolay anlalr rnekler paylamak istiyorum.
java.time paketindeki snflarn genel olarak kurucu metodu private eriim belirleyicisinesahiptir, bu sebeple new anahtar ifadesiyle oluturulamazlar. Onun yerine now, of , from, parsegibi metodlarla yeni nesneler oluturulabilmektedir. java.time paketi ierisindeki zamansalsnflar immutable dir. Bu sebeple bir nesne oluturulduktan sonra ierisindeki veriler kesinlikledzenlenemezler. Bu da mevcut snflar thread-safety hale getirmektedir. ( Bkz. Thread safety& immutability). Bu yazmzda LocalDate , LocalTime , LocalDateTime , ZoneId veZonedDateTime snflarnn kullanmn irdeleyeceiz.
3.1. LocalDateLocalDate snf ile tarihsel zaman temsil edilir. rnein: 10/10/2010 tarihini LocalDateile temsil edebiliriz.
rnekler
"of" metodu ile LocalDate nesnesi oluturulabilir.
LocalDate.of(1988, 07, 16); // 1988-07-16LocalDate.of(1988, Month.JULY, 16) // 1988-07-16 (Month enum)
"now" metodu ile o ann tarihi elde edilir.
LocalDate now = LocalDate.now(); // 2014-04-05
"with*" metodu ile eldeki bir LocalDate iin gn, ay, yl alanlar dzenlenebilir. LocalDatesnf immutable dir. Bu sebeple with metodu farkl bir LocalDate nesne dndrr. O ankinesneyi dzenlemez.
LocalTime
10
LocalDate now = LocalDate.now(); // 2014-04-05
now.withYear(2016); // 2016-04-05
now.withMonth(8).withDayOfMonth(17); // 2014-08-17
now.with(ChronoField.YEAR, 2012).with(ChronoField.MONTH_OF_YEAR, 8).with(ChronoField.DAY_OF_MONTH,3); // 2012-08-03
"plus*" metodu ile eldeki bir LocalDate iin gn, ay, yl alanlar artrlabilir. LocalDate snfimmutabledir. Bu sebeple plus metodu farkl bir LocalDate nesne dndrr. O anki nesneyidzenlemez.
now.plusWeeks(2).plusDays(3).plusYears(3).plusDays(7); //
now.plus(2, ChronoUnit.WEEKS).plus(3, ChronoUnit.YEARS).plus(3, ChronoUnit.DECADES); //
"minus*" metodu ile eldeki bir LocalDate iin gn , ay , yl alanlar azaltlabilir.LocalDate snf immutabledir. Bu sebeple minus metodu farkl bir LocalDate nesnedndrr. O anki nesneyi dzenlemez.
now.minusDays(5).minusMonths(2); //
now.minus(2, ChronoUnit.WEEKS).minus(3, ChronoUnit.YEARS).minus(33, ChronoUnit.DAYS); //
3.2. LocalTimeLocalTime snf ile saatsel zaman temsil edilir. rnein: 20:11 , 18:15:55 saatleriniLocalTime ile temsil edebiliriz. LocalTime ile saat, dakika, saniye, salise temsil edilebilir.
rnekler
LocalDateTime
11
LocalTime now= LocalTime.now();
LocalTime time= LocalTime.of(18, 20, 55); // 18:20:55
time.getHour(); // 18time.getMinute(); // 20time.getSecond(); // 55
LocalTime.NOON; // 12:00LocalTime.MIDNIGHT; // 00:00
LocalTime.parse("10:05"); // 10:05
time.plusSeconds(45).minusSeconds(5).minus(5, ChronoUnit.SECONDS); // 18:20:35
3.3. LocalDateTimeLocalDateTime snf ile hem tarihsel hem saatsel zaman temsil edilir. rnein: 10/10/201015:22:33 zamann LocalDateTime ile snfsal olarak temsil edebiliriz.
rnekler
LocalDateTime now = LocalDateTime.now();
LocalDateTime dateTime = LocalDateTime.of(2014, Month.JANUARY, 3, 4, 5, 45);
dateTime.getYear(); // 2014dateTime.getMonth(); // JANUARYdateTime.getDayOfMonth(); // 3dateTime.getHour(); // 4dateTime.getMinute(); // 5dateTime.getSecond(); // 45
// LocalDateTime2LocalDate ve LocalDateTime2LocalTimeLocalDate date = dateTime.toLocalDate();LocalTime time = dateTime.toLocalTime();
dateTime.minusDays(3).plusYears(3).plusMinutes(3)
ZoneId
12
.minusWeeks(5)
.plusSeconds(2)
.plus(3, ChronoUnit.DECADES)
.minus(3, ChronoUnit.DECADES);
3.4. ZoneIdZoneId snf, dnya zerindeki saat dilimlerinin Java tarafl nesnel karln temsil iinoluturulan yeni bir Java 8 bileenidir.
Java 8 iin tm saat dilimlerinin listelenmesi iin ZoneId snfnn getAvailableZoneIdsmetodu kullanlabilmektedir. rnein aadaki kod, tm saat dilimlerini sral olaraklistelemektedir.
Set zones = ZoneId.getAvailableZoneIds();
zones.stream().sorted().forEach(System.out::println);
Africa/AbidjanAfrica/AccraAfrica/Addis_AbabaAmerica/Argentina/TucumanAmerica/Argentina/UshuaiaAmerica/ArubaAmerica/AsuncionAsia/IstanbulAsia/JakartaAsia/JayapuraEtc/GMT+12Etc/GMT+2Etc/GMT+3Europe/Isle_of_ManEurope/IstanbulEurope/Jersey
O anki allan makinadaki saat dilimi iin ZoneId snfnn systemDefault metodukullanlabilir.
ZonedDateTime
13
ZoneId.systemDefault(); // Europe/Athens
JVM varsaylan saat dilimini mevcut iletim sistemi zerinden almaktadr. Eer istenirsemevcut Java sanal makinesinin varsaylan saat dilimi -Duser.timezone=ifadesiyle dzenlenebilmektedir.
-Duser.timezone=Europe/Istanbul gibi.
3.5. ZonedDateTimeZonedDateTime snf aslnda saat dilimi kattrlm LocalDateTime snfdr desek yeridir.LocalDateTime snfndan fark genel olarak temsil ettii zaman saat dilimi ierir olaraksunmasdr.
rnekler
ZonedDateTime.now();/* 2014-04-05T16:33:16.320+03:00[Europe/Athens] */
ZoneId istanbul = ZoneId.of("Europe/Istanbul");ZonedDateTime.now(istanbul);// 2014-04-05T16:33:16.330+03:00[Europe/Istanbul]
// Japonyada tarih/saat ka?ZonedDateTime.now(ZoneId.of("Japan"));// 2014-04-05T22:33:16.331+09:00[Japan]
Bir ZonedDateTime nesnesi LocalDateTime , LocalDate ve LocalTimekarlklarna dntrlebilmektedir.
LocalDateTime localDateTime = japan.toLocalDateTime();/* 2014-04-05T22:33:16.331 */
LocalDate localDate = japan.toLocalDate(); // 2014-04-05LocalTime localTime = japan.toLocalTime(); // 22:33:16.331
Kaynaklar
[1] http://www.threeten.org/ [2] http://java.dzone.com/articles/introducing-new-date-and-time[3] http://docs.oracle.com/javase/tutorial/datetime/index.html
ZonedDateTime
14
Tekrar grmek dileiyle..
15
Blm 4. Consumer ArayzDaha nceki yazlarmzda Lambda ifadelerinden ve Fonskiyonel arayzlerden bahsetmitik.imdi ise, java.util.function paketi altnda yer alan ve gml olarak bulunanfonksiyonel arayzlere deineceiz.
java.util.function paketi altnda, farkl amalar iin bulunan hazr arayzler bulunmaktadr.Java 8 ierisinde Lambda deyimlerinin kullanlabilir klnmasnda, java.util.function paketialtndaki arayzler kullanlmaktadr. Bu fonksiyonel arayzlere java.util.function1 adresindengrebilirsiniz.
Bu yazmzda ise, fonksiyonel arayzlere giri dncesiylejava.util.function.Consumer arayznden ve nasl kullanldndan bahsedeceiz.Consumer arayz accept isimli tek bir metoda sahiptir. Bu fonksiyonun bulunu amac,tketim operasyonlarnda kullanlmasdr. Tketimden kast edilen ise, metoda girdi olmasfakat kt olmamasdr. Metod girdisinin tipi ise jenerik olarak T harfi ile temsil edilmitir. Tyerine, istee gre herhangi bir Java tipi gelebilir. Biz String tipini kullanacaz.
@FunctionalInterfacepublic interface Consumer {
void accept(T t);
}
Consumer arayz, yukarda grld zere bir fonksiyonel arayzdr. Bir arayzn,fonksiyonel olarak nitelenebilmesi iin, tek bir soyut metoda sahip olma art vardr. Zaten busayede, fonksiyonel arayzler Lambda deyimlerine yknebilmektedirler.
4.1. Java 8 ncesi
Java 8 ncesine gre Consumer arayz trnden bir nesneyi anonim bir snf ile oluturulm.
Consumer consumer = new Consumer() { @Override public void accept(String msg) { System.out.println(msg);
1 http://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
Java 8 sonras
16
}};
consumer.accept("Merhaba Dnya");
Grld zere bir anonim snf oluturduk ve accept metodunu tkettik.
4.2. Java 8 sonrasJava 8 sonras iin anonim fonksiyonlar yerine Lambda deyimlerini kullanabilmekteyiz.rnein yukardaki anonim snf aadaki yer alan Lambda deyimi ile yer deitirebiliriz.
Consumer consumer = (String msg) -> { System.out.println(msg);};
consumer.accept("Merhaba Dnya");
Lambda deyimlerinde odaklanmas gereken nokta, fonksiyonel arayzn tek metodunun sahipolduu metod girdi tipi, says,sras ve metod kt tipidir. Bu sayede kod satr olarak tasarufedilmektedir.
4.3. Lambda deyimleri aklldrLambda fonksiyonlarnda tanmlanan metod girdi tanmlamalarnda, istenirse tiptanmlamasndan feragat edilebilir. Yani yukardaki Lambda deyimini aadaki gibi yazabiliriz.
Consumer consumer = (msg) -> { System.out.println(msg);};
consumer.accept("Merhaba Dnya");
Grld gibi, (String msg) tanmlamasn (msg) yapabildik. Sol tarafta zaten String tip bilgisiyer aldndan, compiler metod girdisinin tipini buradan elde edecektir. Tip tanmlamalarndanferagat ettiimiz gibi parantezden de kurtulabiliriz.
Consumer consumer = e -> { System.out.println(e);};
Consumer arayznerede kullanlyor?
17
consumer.accept("Merhaba Urans");
4.4. Consumer arayz nerede kullanlyor?JDK 8 in ekirdeinde java.util.function arayzleri halihazrda kullanlmaktadr. rneinIterable arayznn ierisinde forEach metodunda Consumer arayz kullanlmaktadr.
public interface Iterable {
...
default void forEach(Consumer
Lambda deyimlerini MetodReferanslar ile kullanabiliriz.
18
public class App{
public static void listele(String e) { System.out.println(e); }
}
Dikkat edilirse bu metodun girdi ve kt normu, Consumer#accept metodunun girdi ve ktbiimiyle birebir ayndr. Bu sebeple, listele metodu metod referans olarak Consumer tipi iinkullanlabilirdir.
Consumer consumer= App::listele;
consumer.accept("Merhaba Dnya");
Bir metodu referans olarak kullanabilmek iinifadesi kullanlmaktadr. imdi metod referans kullanmn rnek olarak forEach metoduzerinde deneyelim.
List names = Arrays.asList("Ali", "Veli", "Selami");
names.forEach(App::listele);
App#listele metodunun bir benzerinin yazlm zaten PrintStream snf ierisinde var.
List names = Arrays.asList("Ali", "Veli", "Selami");
names.forEach(System.out::print);
// veya
names.forEach(System.out::println);
imdilik bu kadar, tekrar grmek dileiyle.
19
Blm 5. Lambda rneklerijava.util.function paketi altnda bir ok fonksiyonel arayz bulunmaktadr. Buarayzlerin temel amac, farkl tipteki Lambda ifadelerine temel oluturmaktr.
5.1. Consumer Arayz
@FunctionalInterfacepublic interface Consumer {
void accept(T t); // t-> {}
}
T tipindeki parametreyi alr ve tketir/iler. Geriye deer dndrmez (void). T burada herhangibir snf tipi olabilir.
Consumer Arayz rnek
Consumer consumer = word -> { System.out.println(word); // Merhaba Dnya };
consumer.accept("Merhaba Dnya");
5.2. BiConsumer Arayz
@FunctionalInterfacepublic interface BiConsumer {
void accept(T t, U u); // (t,u) -> {}}
T ve U tiplerinde iki parametre alr ve bu parametreleri tketir. Geriye deer dndrmez.
BiConsumer Arayz rnek
BiConsumer biConsumer = (name, age) -> {
Function Arayz
20
System.out.println(name+":"+age); // Alinin ya:25 };biConsumer.accept("Ali'nin ya",25);
5.3. Function Arayz
@FunctionalInterfacepublic interface Function {
R apply(T t); // t-> r
}
T tipinde bir parametre alr, iler ve R tipinde bir deer dndrr.
Function Arayz rnek
Function function = t -> Math.pow(t,2);Integer result = function.apply(5);System.out.println(result); // 25
5.4. UnaryOperator Arayz
@FunctionalInterfacepublic interface UnaryOperator extends Function {
}
Function trndendir. Eer T ve R tipleri ayn trden ise, ismi UnaryOperator olur.
UnaryOperator Arayz rnek
UnaryOperator unaryOperator = a -> Math.pow(a,5);Integer result = unaryOperator.apply(2);System.out.println(result); // 32
BiFunction Arayz
21
5.5. BiFunction Arayz
@FunctionalInterfacepublic interface BiFunction {
R apply(T t, U u); // (t,u) -> r}
T ve U tiplerinde iki parametre alr, R tipinde deer dndrr. T, U ve R herhangi bir snf tipiolabilir. Function#apply tek parametre alrken Bi* iki parametre alr.
BiFunction Arayz rnek
BiFunction biFunction = (a, b) -> "Sonu:" + (a + b);String result = biFunction.apply(3,5);System.out.println(result); // Sonu: 8
5.6. BinaryOperator Arayz
@FunctionalInterfacepublic interface BinaryOperator extends BiFunction {
}
BiFunction trndendir. T, U ve R ayn tipte ise BinaryOperator kullanlabilir.
BinaryOperator Arayz rnek
BinaryOperator binaryOperator = (a, b) -> a + b;Integer result = binaryOperator.apply(3,5);System.out.println(result); // 8
5.7. Predicate Arayz
@FunctionalInterfacepublic interface Predicate {
BiPredicate Arayz
22
boolean test(T t); // t-> true/false}
T tipimde bir parametre alr, arta bal olarak true/false deer dndrr.
Predicate Arayz rnek
Predicate predicate = a -> (a > 0);
boolean pos = predicate.test(5); // trueboolean neg = predicate.test(-5); // false
5.8. BiPredicate Arayz
@FunctionalInterfacepublic interface BiPredicate {
boolean test(T t, U u); // (t,u) -> true/false}
T ve U tiplerinde iki parametre alr, arta bal olarak true/false dndrr.
BiPredicate Arayz rnek
BiPredicate biPredicate = (a, b) -> (a > b);
boolean bigger = biPredicate.test(5,4); // trueboolean lower = biPredicate.test(5,7); // false
5.9. Supplier Arayz
@FunctionalInterfacepublic interface Supplier {
T get(); // () -> t}
Hi parametre almaz, T tipinde bir deer dndrr. Factory pattern iin uygundur.
Supplier Arayz
23
Supplier Arayz rnek
Supplier supplier = () -> new ArrayList();List liste = supplier.get();liste.add("Ali");liste.add("Veli");liste.add("Selami");
Tekrar grmek dileiyle
24
25
Blm 6. Notasyonlar ve TekrarlNotasyonlarNotasyonlar (Annotations) Java 5den beri Java ortamnda kullanlan bileenlerdir.Notasyonlar genel olarak bir bileene zellik katma veya konfigrasyon amal olarakkullanlmaktadr. Bu yazda notasyonlarn genel zelliklerinden ve Java 8 RepeatedAnnotations yeniliinden bahsedilecektir.
Notasyonlar @ iaretiyle balayan arayzlerdir ve notasyonlar iinde alanlartanmlanabilmektedir.
rnein;
@Single Notasyonu
public @interface Single {
String value();
}
Notasyonlar eitli alanlara uygulanabilmektedir. Bu alanlar;
Nereye uygulanabilir? Aklama
TYPE Snf, arayz, soyut snf balarna
METHOD Metod balarna
FIELD Global alan balarna
PARAMETER Metod parametrelerine
CONSTRUCTOR Constructor bana
ANNOTATION_TYPE Notasyonlarn bana
PACKAGE Paket deklarasyonu bana
Hangi notasyonun nereye veya nerelere uygulanabilecei, notasyonu yazan tarafndanbelirtilmektedir. Bu belirtim ilemi ise @Target isimli notasyon ile salanmaktadr.
rnek 1
@Target({ElementType.METHOD})
26
public @interface Single {
String value();
}
@Single notasyonunun uygulanabilirlik alan METHOD olarak tanmland iin, @Singlenotasyonu sadece metod balarnda kullanlabilir. Dier alanlarda kullanlamaz, kullanlmayakalklrsa derleme zamannda hata alnr.
Uygulama 1
@Single // Buraya konamazpublic class App {
@Single // Buraya konabilir public void doIt() {
}}
rnek 2
@Target({ElementType.METHOD,ElementType.TYPE})public @interface Single {
String value();
}
imdi ise @Single notasyonu hem metod balarna hem de snf, arayz, soyut snf gibibileenlerin balarna eklenebilir.
Uygulama 2
@Single // Artk buraya da konabilirpublic class App {
@Single // Buraya uygulanamaz :( String message = "Merhaba Dnya";
@Single // Buraya konabilir public void doIt() {
Notasyonlar ve Alanlar
27
}}
@Target notasyonu ile yaplan aslnda, notasyonun uygulanabilirlik alann, yani yetkialann belirlemektir. rnein Uygulama 2'de uygulanabilirlik alan olarak METHOD veTYPE belirlenmitir. Bu sebeple sadece bununla ilgili ksmlara @Single notasyonuuygulanabilir.Mesela rnekte olduu gibi global alanlara uygulanamaz. Eer buraya dauygulanabilir olmas istenirse FIELD enum bileeni @Target notasyonuna eklenmelidir.
6.1. Notasyonlar ve AlanlarNotasyonlar konfigrasyon amacyla kullanlrken, barndrd deiken alanlarndanfaydalanlmaktadr. Bu alanlarn tipi, ismi ve gerekirse varsaylan deeri tanmlanabilmektedir.
Fakat bu alanlarda tip snrlamas vardr, bu tipler unlar olabilir;
String
Temel tipler
Class
Bir Enum tipi
Dier bir notasyon tipi
Yukardaki tiplerin dizi tipleri
@Single notasyonunu dnrsek String trnde value adnda tek bir alana sahiptir.Deer atamas ise deklerasyon annda () ierisinde yaplmaktadr.
rnein;
@Single(value="Merhaba Dnya")public interface Hello {
}
Notasyonlar iin value alannn zel bir anlam vardr. Eer baka bir alana deer atamasyaplmayacaksa value yazlmasa bile bu deer atamas value alanna yaplmaktadr.
rnein;
@Single("Merhaba Dnya")
Notasyonlara Eriim
28
public interface Hello {
}
Denktir @Single(value="Merhaba Dnya")
6.2. Notasyonlara EriimNotasyonlarn nereye uygulandklar ve ierisinde barndrdklar veriler derleme zamannda(compile time) veya alma zamannda (runtime) elde edilebikmektedir. Fakat bir notasyonahangi zamanlarda eriilebilecei @Retention isimli notasyon ile belirtilmelidir. Retention(tutma) politikasnn 3 tipi vardr.
SOURCENotasyonlar derleme zamannda yok saylr.
CLASSNotasyonlar derleme zamannda snf ierisinde bulundurulur, fakat alma zamanndabulunmas zorunlu deildir. Varsaylan hal budur.
RUNTIMENotasyonlar alma zamannda eriilmek zere snf ierisinde bulundurulur. almazamannda eriim Java Reflection API ile yaplr. Sk kullanlan hal budur.
NotRastgele 10 notasyon belirleyip, @Retention notasyonunu incelediinizde %90 zeriarlkta tutma politikasnn RUNTIME olarak yaplandrldn grebilirsiniz.
rnein;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME) public @interface Single {
String value();
}
Metod ve Snflarn bana uygulanabilir.alma zamannda bu notasyona eriilebilir.
Yukarda @Target ve @Retention notasyonlaryla yaplandrlm kullanma hazr bir@Single notasyonunu gryoruz.
NotasyonlarnTekrarl Kullanlmas
29
6.3. Notasyonlarn Tekrarl KullanlmasJava 8 ncesinde bir notasyon, iki kere ayn yerde kullanlamamaktayd.
Hatal kullanm rnei;
@Single("Merhaba")@Single("Jupiter")public class App {
}
rnein @Single notasyonu yukardaki gibi ayn alanda kullanlamaz. Bu snrllk Java 8ncesinde ikincil bir notasyon zerinden almaktayd.
rnein;
@Target({ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)public @interface Multiple {
Single[] value();}
Multiple notasyonu Single tipli diziler barndrabilen bir value alanna sahiptir. ArtkMultiple notasyonu zerinden birden fazla @Single notasyonu uygulanabilirdir.
Doru kullanm rnei;
@Multiple(value = { @Single("Merhaba"), @Single("Jupiter")})public class App {
}
NOTE : Notasyonlarda dizi tipli alanlara atamamalar, { } arasnda virgl , ile ayrlm olarakyaplmaktadr.
Java 8 ile birlikte bu snrllk ortadan kalkmtr. Bu snrll ortadan kaldrmak iin@Repeatable notasyonundan faydalanlmaktadr.
NotasyonlarnTekrarl Kullanlmas
30
@Repeatable(Multiple.class) // Dikkat
@Target({ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)public @interface Single { String value();}
@Repeatable notasyonu tekrarlayacak notasyona uygulanmaktadr. @Repeatablentoasyonunun value alanna ise, sarmalayc notasyonun snf tipi tanmlanmaldr. Bu yollatekrarl notasyonlar alt alta, yan yan istendii kadar tanmlanabilmektedir.
rnein;
@Single("Merhaba")@Single("Urans")public class App {
public static void main(String[] args) {
Class app = App.class;
Single[] notz = app.getAnnotationsByType(Single.class);
for (Single not : notz) {
System.out.println(not.value()); // Merhaba // Urans }
}
}
App snfnn snf tipini alr.App snfna uygulanm tm Single tipli notasyonlar bulur.Tm uygulanm Single notasyonlarn dolar.O anki Single notasyonunun value() alann ktlar.
Tekrar grmek dileiyle.
31
Blm 7. Method ReferenceJava programlama dilinde metodlar, snflarn iinde bulunan i birimleridir.
Metodlara eriimin ise statik olup olmadna gre iki eriim biimi vardr. Statikmetodlara snf zerinden eriilebilirken, statik olmayan metodlara nesne zerinden eriimsalanabilmektedir.
Java 8 ile beraber metod birimleri, bir lambda ifadesine, dolaysyla bir fonksiyonel arayzekarlk olarak referans verilebilmektedir.
Lambda ifadeleri yazlrken, tek metoda sahip arayzn (fonksiyonel arayz) metod girdi vekts baz alnmaktadr. Eer daha nce yazdnz bir metodun girdi ve kts, bir fonksiyonelarayz metodunun girdi ve ktsna birebir uyuyorsa, o metod bir lambda deyimi yerinekullanlabilmektedir.
rnein;
Consumer arayz T trnde tek bir parametre alr. Metod dn void 'dir.
@FunctionalInterfacepublic interface Consumer {
void accept(T t); // t-> {}
}
Yukardaki Consumer arayz trnden bir nesneyi, e {} lambda deyimiyleoluturabiliriz.
Consumer consumerWithLambda = e-> {
};
Lambda ifadeleri yazarken metod girdi ve ktsna odaklandmza gre, lambda deyimiylebirebir rten metodlar, lambda deyimleri yerine kullanabilir miyiz? Bunu aadaki metodzerinden dnelim.
public void herhangiBirMetod(String e){
}
Bir metodu referans vermek
32
Yani herhangiBirMetod metodunun imzasyla Consumer arayznn acceptmetodunun imzas birbiriyle ayndr. herhangiBirMetod , String trnden tek bir parametrealmaktadr, metod dn ise void 'dir. Bu uyum neticesinde eer istenirse, bu metodunreferans ile Consumer trnden bir nesne oluturulabilir.
7.1. Bir metodu referans vermekJava programlama dilinde bir metodun nasl referans verilecei metodun statik olupolmadna gre deimektedir. Bir metodun referans olarak verilebilmesi iin ise :: ikilisikullanlr.
Statik metodlarda Statik metodlar snfa ait bileenlerdir. Bu yzden eriim kurulurken dahiliolduu snf zerinden eriim kurulur.
rnein;
Consumer consumerWithMetRef = ::herhangiBirMetod;
Statik olmayan metodlarda Statik olmayan metodlar nesneye ait bileenlerdir. Bu sebeplenesnenin referans zerinden eriilmelidirler.
rnein;
Consumer consumerWithMetRef = ::herhangiBirMetod;
rnek 1 imdi birka rnek ile metod referanslar deneyimleyelim. Aada"Ali" , "Veli" , "Selami" verilerini ieren bir List nesnesi bulunmaktadr. Bu nesneninise, forEach isimli metodu bulunmaktadr. Bu nesnenin kabul ettii parametre iseConsumer trndendir.
List names= Arrays.asList("Ali,Veli,Selami");
names.forEach(new Consumer() { @Override public void accept(String s) { System.out.println(s); }});
Srayla konsole ktlar.imdi bu rnei Lambda ifadesiyle yeniden aadaki gibi yazabiliriz.
Bir metodu referans vermek
33
List names= Arrays.asList("Ali,Veli,Selami");
names.forEach(s->{ System.out.println(s);});
Lambda ifadesi, satr says baznda kodu iyice ksaltt. imdi bu ayn ii metod referanskullanarak yapalm.
public class App{
static List names= Arrays.asList("Ali,Veli,Selami");
// Statik metod public static void herhangiBirMetod(String s){ System.out.println(s); }
// Non-statik metod public void digerBirMetod(String s){ System.out.println(s); }
public static void main(String[] args){
names.forEach(App::herhangiBirMetod);
// veya
App app=new App();
names.forEach(app::digerBirMetod);
// veya
names.forEach(System.out::println); }
}
Statik metodu referans vermekNon-statik metodu referans vermekDier bir rnek
Bir metodu referans vermek
34
rnek 2 Collections#sort metodu ile bir dizi nesneyi sralamak istiyoruz diyelim.Bu sralamay, metodun 2. parametresinde Comparator trnden bir nesne ile kontroledebiliriz.
List numbers = Arrays.asList(5, 10, 1, 5, 6);
Collections.sort(numbers, new Comparator() { @Override public int compare(Integer o1, Integer o2) { return o1 - o2; }});
Fonksiyonel olarak Comparator arayz vejava.util.BiFunction arayz birebir ayndr.
imdi anonim olarak oluturulan Comparator trnden nesneyi Lambda ifadeleriyle yenidenyazalm.
List numbers = Arrays.asList(5, 10, 1, 5, 6);
Collections.sort(numbers, (o1, o2) -> o1 - o2)
imdi ise Lambda deyimi yerine metod referans kullanarak bu ii yapalm.
public Integer sirala(Integer o1, Integer o2){
return o1 - o2;
}
public void birMetod(){
List numbers = Arrays.asList(5, 10, 1, 5, 6);
Collections.sort(numbers, this::sirala); }
Lambda yerine metod referansMetod referans kullanmak var olan i mantn kolay bir biimde referans vermeye olanaksalamaktadr.
Bir metodu referans vermek
35
Tekrar grmek dileiyle.
36
37
Blm 8. Default MethodsJava 8 ile beraber varsaylan metod zellii bir dil zellii olarak Javaya katld. Varsaylanmetodlarn literatrde birok farkl isim ile anlmaktadr. Bunlar;
Default method
Defender method
Virtural extension method
Java 8 evvelinde arayz bileenlerinde dilin tasarm asndan sadece soyut metodlarbulunabilmekteydi. Somut yani gvdeli metodlar bulunamamaktayd. Aada doru ve yanlkullanmlara birer rnek grmekteyiz.
Doru bir kullanm rnei
public interface Arac {
void gazla(); }
Soyut, gvdesiz metod, doru kullanm.Yanl bir kullanm rnei
public interface Arac { void gazla() { // bla bla bla
}; }
Somut, gvdeli metod, yanl kullanm.
8.1. Varsaylan Metoda Giri
Java 8 ile birlikte bir arayz bileeninde bir yada daha fazla sayda defender methodtanmlanabilmektedir. Varsaylan metodlar default anahtar kelimesiyle tanmlanmaktadr.rnein;
public interface Arac {
Varsaylan Metoda Giri
38
default void gazla(){ // Defender method
System.out.println("Ara: alyor..");
}
void dur(); // Soyut metod }
numaral ksmdaki gazla() metodu default anahtar ifadesi araclyla birvarsaylan metoda dntrlmtr. Varsaylan metodlar arayzlere i mantyerletirmeye msade eden zel metodlardr.numaral ksmda ise olaan biimde gvdesiz bir metod bulunmaktadr.
Varsaylan metoda sahip bir arayzden treyen alt snflar, arayzn sahip olduu tmdefender metodlar tketebilmektedir.
Arac trnden Minibus snf
public class Minibus implements Arac {
@Override public void dur() { System.out.println("Minibs duruyor.."); }
}
rnein yukarda yer alan Minibus snf Arac`arayz trnden bir snftr.Bu sebeple, Minibus snf trnden nesneler `Arac arayz ierisindekigazla() metodunu koturabilecektir.
Minibus minibus=new Minibus();
minibus.gazla();
minibus.dur();
Arac iindeki gazla() varsaylan metodu koturuluyor.Minibus iindeki dur() metodu koturuluyor.
Ara: alyor..Minibs duruyor..
Varsaylanmetodlarda akma
39
Yukarda grld zere, normalde Minibus snf ierisinde gazla() metodubulunmamasna ramen, Arac arayz iindeki defender metodu koturabildi.
8.2. Varsaylan metodlarda akmaEer bir Java snf, ayn isimde varsaylan metoda sahip birden fazla arayz uygularsa,derleme zamannda hata ile karlalr.
Ayn isimde varsaylan metodlara sahip iki arayz
public interface Arac {
default void gazla(){ System.out.println("Ara: alyor.."); }
void dur();}
public interface Tasit {
default void gazla(){ System.out.println("Tat: alyor.."); }}
rnein (1) numarada Arac , (2) numarada da Tasit arayzleri gazla() adndavarsaylan metodlara sahiptir.
imdi bu iki tr birden uygulayan bir Otobus snf yazalm.
akma durumu rnei
public class Otobus implements Arac, Tasit {
@Override public void dur() { System.out.println("Ara duruyor.."); }}
Otobus snf bu haliyle derlendiinde aadaki derleme hatas alnacaktr.
akma durumu hata mesaj
Varsaylanmetodlarda akma
40
Error:(6, 8) java: class com.kodcu.def.Otobus inherits unrelated defaults for gazla() from types com.kodcu.def.Arac and com.kodcu.def.Tasit
nk ortada Otobus snfnn hangi gazla() metodunu koturacana dair bir ikilemvardr. JVM ikilem durumlarn hi sevmez, ona bir seim ansz sunmalyz. Bu akmadurumu, varsaylan metodu Otobus snf iinde yeniden dzenlenerek ( @Override ederek)giderilebilmektedir.
akma durumunun giderilmesi - 1
public class Otobus implements Arac, Tasit {
@Override public void dur() { System.out.println("Ara duruyor.."); }
@Override public void gazla() { System.out.println("Otobs alyor.."); }}
Otobus snfna gazla() metodu ekleyerek yeniden dzenlendiinde artk akmadurumu giderilmi durumdadr. Snf bu haliyle Otobs alyor.. mesajnktlayacaktr.
Fakat burada farkl bir ihtiya daha gze batmaktadr. Bu durumda Arac veya Tasitarayzleri iindeki akan gazla() metodlar nasl alt snflarda kullanlabilir?
te bu noktada .super.() biimi ile arayzlerdekivarsaylan metodlar akma olmadan koturulabilmektedir.
akma durumunun giderilmesi - 2
public class Otobus implements Arac, Tasit {
@Override public void dur() { System.out.println("Ara duruyor.."); }
@Override public void gazla() {
Varsaylan metodlar veFonksiyonel arayzler
41
Arac.super.gazla(); /* veya */
Tasit.super.gazla(); }}
Arac arayznn gazla() metodunu kotururTasit arayznn gazla() metodunu koturur
8.3. Varsaylan metodlar ve Fonksiyonel arayzlerFonksiyonel arayzler, tek bir gvdesiz metoda sahip zel arayzlerdir. Eer bir Javaarayznn iinde birden fazla sayda soyut metod varsa, bu arayzler fonksiyonel arayzolamamaktadr. Fonksiyonel arayzlerin en nemli zellii, Lambda ifadesi olarak temsiledilebilmesidir.
Arayzler iinde tanmlanan varsaylan metodlar ise, bir arayzn fonksiyonel olabilmesinietkilememektedir. nk yazlan Lambda deyimleri, arayz iindeki tek bir soyut metodaodakl olarak dntrlmektedir.
public interface Arac {
default void gazla(){ System.out.println("Ara: alyor.."); }
void dur();}
rnein yukardaki Arac arayzn fonksiyonel arayz olabilirlii asndan deerlendirelim.Arac snfnn fonksiyonel arayz olabilmesi iin tek bir soyut metoda sahip olmasgerekmektedir. Arac arayz iindeki dur() metodu soyuti gvdesiz bir metod olduu iinbir fonksiyonel arayzdr. gazla() metodu ise bir varsaylan metod olduundan fonksiyonelolabilirlie bir etkisi yoktur. Bu noktada, Arac arayz bir fonksiyonel arayz olduundanLambda deyimi olarak yazlabilecektir. Tabi ki Lambda deyimi, dur() isimli soyut metoddikkate alnarak yazlmaldr.
Arac otobus = ()-> System.out.println("Otobs duruyor.."); otobus.gazla();
Varsaylan metodlar ve JDK
42
otobus.dur();
Ara: alyor..Otobs duruyor..
Yukarda (1) numarada yazl Lambda deyimi, dur() metoduna karlk olarak tanmlanmtr.Bu sebeple Arac arayz trnden bir nesne oluturmaktadr.
8.4. Varsaylan metodlar ve JDKJDK 1.8 ierisinde baz noktalarda varsaylan metodlar kullanlmaktadr.java.util.Collection arayznde bunu fazlaca grmekteyiz.
public interface Collection extends Iterable {
...
default boolean removeIf(Predicate
Varsaylan metodlar ve JDK
43
}
Collection snf iindeki removeIf , stream , parallelStream ve spliteratormetodlar varsaylan metodlardr. Bu sebeple Collection trnden tm nesneler buvarsaylan metodlar miras alarak tketebilmektedir.
Collection arayznde olduu gibi Iterable arayznde de varsaylan metodbulunduunu grebiliyoruz.
@FunctionalInterfacepublic interface Iterable {
Iterator iterator();
default void forEach(Consumer
44
45
Blm 9. Stream APIJava 8 ierisinde ynsal verileri kolay ilemek asndan Stream API yenilii getirilmitir.
Stream API ynsal veriler zerinde almaktadr. Ynsal veri deyince ilk akla gelenhi phesiz diziler ( byte[] , String[] gibi ) ve Java Collection API bileenleridir( List , Set gibi)
Stream API, bu gibi ynsal veriler zerinde eitli sk kullanlan operasyonlar kolay, zl veverimli bir biimde koturmaya olanak tanmaktadr. Bu operasyonlardan en sk kullanlanlaraadaki gibidir.
Metod Aklama
filter Filtreleme
forEach iterasyon
map Dntrme
reduce ndirgeme
distinct Tekilletirme
sorted Sralama
limit Aralk alma
collect Tre dnm
count Sayma
Bu operasyonlar ve daha fazlas java.util.stream.Stream arayz iinde bulunmaktadr.Stream arayznn sadeletirilmi hali aadaki gibidir.
public interface Stream extends BaseStream {
Stream filter(Predicate
Stream nesnesinasl elde edilir?
46
IntStream flatMapToInt(Function
New I/O ile
47
...
default Stream stream() { return StreamSupport.stream(spliterator(), false); }
default Stream parallelStream() { return StreamSupport.stream(spliterator(), true); }
...
}
stream() metodu ile elde edilen Stream nesnesi yapaca ilemleri ardl olarak yaparken,parallelStream() metoduyla elde edilen Stream nesnesi, baz operasyonlar paralel olarakkoturabilmektedir.
rnein;
List names = Arrays.asList("Ali","Veli","Selami");
Stream stream = names.stream();
Stream parallelStream = names.parallelStream();
Collection trnden bir nesneArdk streamParalel stream
9.1.2. New I/O ile
Java ierisindeki baz I/O snflar zerinden Stream nesneleri elde edilebilmektedir.
Path dir = Paths.get("/var/log");
Stream pathStream = Files.list(dir);
/var/log dizinine denk gelen bir Path nesnesiFiles#list metodu zerinden bir Stream nesnesi
IntStream, DoubleStream,LongStream ile
48
9.1.3. IntStream, DoubleStream, LongStream ile
Stream arayz BaseStream arayznden tremektedir. Stream arayzne benzerbiimde IntStream, DoubleStream ve LongStream arayzleri de BaseStream arayzndentremektedir.
Stream arayz trnden nesneler tm veri tipleriyle almak iin oluturulan bir arayzken,buradaki eleman ise, sadece snf bandaki tip ile zel olarak almak iin oluturulanarayzlerdir.
rnein;
IntStream intOf = IntStream.of(1, 2, 3);
IntStream intRange = IntStream.range(1, 10);
DoubleStream doubleOf = DoubleStream.of(1.0, 3.5, 6.6);
LongStream longOf = LongStream.of(3, 5, Long.MAX_VALUE,9);
LongStream longRange = LongStream.range(1, 100);
(1,2,3) ieren IntStream nesnesi(1,,10) arasn ieren IntStream nesnesi(1.0, 3.5, 6.6) ieren DoubleStream nesnesi(3, 5, Long.MAX_VALUE,9) ieren LongStream nesnesi(1,,100) arasn ieren LongStream nesnesi
9.2. Stream API rnekleriBu ksmda eitli Stream API metodlar ile kk uygulamalar yer almaktadr.
9.2.1. forEach
Stream ierisindeki ynsal veriyi tek tek tketmek iin yaplandrlmtr. Consumer arayztrnden bir parametre bekler.
List names = Arrays.asList("Ali","Veli","Selami","Cem","Zeynel","Can","Hseyin");
Stream stream = names.stream();
stream.forEach(name -> {
filter
49
System.out.println(name);});
// veya stream.forEach(System.out::println);
9.2.2. filter
Stream ierisindeki ynsal veri zerinde szme ilemi yapar. Predicate arayz trnden birparametre ile filtreleme ilemini yapar.
List names = Arrays.asList("Ali", "Veli", "Selami", "Cem", "Zeynel", "Can", "Hseyin");
Stream stream = names.stream();
Predicate predicate = name -> name.length() < 4;
Stream filtered = stream.filter(predicate);
filtered.forEach(System.out::println);
Stream nesnesi elde ediliyor.Predicate sorgusu hazrlanyorSzme ilemi yaplyor, yeni bir Stream nesnesi sunuluyor.Listeleniyor. [Ali, Cem, Can]
Stream nesneleri tek kullanmlktr. Stream nesnesinin ou metoduyeni bir Stream nesnesi sunmaktadr. Bu sebeple tm operasyonlarzincirlemeli olarak yaplabilmektedir.
rnein;
names .stream() .filter(name -> name.length() == 4) .forEach(System.out::println);
9.2.3. distinct
Bir Stream ierisinden tekrarl veriler karlmak isteniyorsa distinct metodundanfaydalanlabilir.
sorted
50
IntStream stream = IntStream.of(1, 1, 2, 3, 5, 8, 13, 13, 8);
stream .distinct()
.forEach(System.out::println);
IntStream nesnesi[1,2,3,5,8,13]
9.2.4. sorted
Stream ierisindeki ynsal verinin sralanm Stream nesnesini dndrr.
IntStream stream = IntStream.of(13, 1, 3, 5, 8, 1, 13, 2, 8);
stream .sorted()
.forEach(System.out::println);
IntStream nesnesi[1,1,2,3,5,8,8,13,13]
9.2.5. limit
Bir Stream yn ierisindeki ilk N veri barndran yeni bir Stream nesnesi sunmaktadr.
LongStream range = LongStream.range(1, 10000);
range .limit(10)
.forEach(System.out::println);
(1,,10000) arasn ieren bir Streamlk 10 veri : [1,,10]
9.2.6. count
Stream ierisindeki eleman saysn hesaplar.
collect
51
IntStream range = IntStream.range(1, 10);IntStream rangeClosed = IntStream.rangeClosed(1, 10);
System.out.println(range.count());
System.out.println(rangeClosed.count());
910
9.2.7. collect
Stream trnden nesneler, yn verileri temsil eden zel nesnelerdir. Fakat Stream biimi birveri yaps sunmamaktadr. collect metodu arlkl olarak , Stream nesnelerini baka biimdekibir nesneye, veri yapsna dntrmek iin kullanlmaktadr.
Stream#collect metodu Collector trnden bir parametre kabul etmektedir. Bu parametreile istendik tre dnm salanmaktadr. Collector trnden arayzler, Collectorssnfnn eitli statik metodlaryla elde edilebilmektedir.
List names = Arrays.asList("Ali", "Veli", "Selami", "Veli", "Selami", "Can", "Hseyin");
List list = names.stream().collect(Collectors.toList());
Set set = names.stream().collect(Collectors.toSet());
Long count = names.stream().collect(Collectors.counting());
String collect = names.stream().collect(Collectors.joining(" - "));
Map integerListMap =
names.stream().collect(Collectors.groupingBy(name -> name.length()));
Stream nesnesinden List nesnesi retir.List["Ali", "Veli", "Selami", "Veli", "Selami", "Can", "Hseyin"]Stream nesnesinden Set nesnesi retir.Set["Ali", "Veli", "Selami","Can", "Hseyin"]Stream nesnesinin eleman saysn retir.7
map
52
Stream nesnesini birletirir.Ali - Veli - Selami - Veli - Selami - Can - HseyinStream nesnesini isim uzunluuna gre gruplar.
Tablo 9.1. Map nesnesinin temsili tablogrnm
Key Value
Ali3
Can
Veli4
Veli
Selami6
Selami
7 Hseyin
9.2.8. map
Stream iindeki ynsal olarak bulunan her bir veriyi dntrmeye olanak tanr. Dntrmilemi Stream ierisindeki her bir e iin ayr ayr yaplmaktadr. Stream#map metoduFunction trnden bir parametre beklemektedir.
rnek 1; Bir List iindeki her bir enin harflerini bytelim.
List names = Arrays.asList("Ali", "Veli", "Selami", "Cem");
Stream stream = names.stream();
Stream upperStream= stream.map(name -> name.toUpperCase());
List upperNames = upperStream.collect(Collectors.toList());
Stream nesnesi elde ediliyorHer bir ismin harfleri bytlyorList["AL","VEL","SELAM","CEM"]
rnek 2; 1,5 aras saylarn karelerini hesaplayalm.
IntStream
reduce
53
.rangeClosed(1, 5) .map(n -> n*n)
.forEach(System.out::println);
[1, 4, 9, 16, 25]
9.2.9. reduce
Bir Stream ierisindeki verilerin teker teker ilenmesidir. Teker teker ileme srecinde, birnceki admda elde edilen sonu bir sonraki adma girdi olarak sunulmaktadr. Bu sayedeylml bir hesaplama sreci elde edilmi olmaktadr.
Stream#reduce metodu ilk parametrede identity deeri, ikinci parametrede iseBinaryOperator trnden bir nesne kabul etmektedir.
reduce ileminde bir nceki hesaplanm deer ile sradaki deer bir ileme tabi tutulmaktadr.leme balarken bir nceki deer olmad iin bu deer identity parametresindetanmlanmaktadr.
rnek 1; 1,2,3,4,5 saylarnn toplamn hesaplayalm.
int result = IntStream .of(1, 2, 3, 4, 5) .reduce(0, (once, sonra) -> { System.out.format("%d - %d %n", once, sonra); return once + sonra; });
Toplama ileminde 0 etkisiz eleman olduu iin, identity deeri 0 seildi.
Uygulama altrldnda 15 sonucu elde edilir. reduce iindeki Lambda ifadesinde iseaadaki kt elde edilir.
0 - 1 1 - 2 3 - 3 6 - 410 - 5
nce hesaplanm deeri, Sonra ise sradaki deeri temsil etmektedir. Bir admda kanhesaplamann sonucu, bir sonraki admda (satrda) nce stununa sunulmaktadr.
map & reduce
54
nce Sonra Hesaplama
0 1 0+1 #
1 2 1+2 #
3 3 3+3 #
6 4 6+4 #
10 5 10+5 = 15
rnek 2; 1,2,3,4,5 saylarnn arpmn hesaplayalm.
// Lambda ileint result = IntStream .of(1, 2, 3, 4, 5) .reduce(1, (once, sonra) -> once*sonra);
// veya Method reference ileresult = IntStream .of(1, 2, 3, 4, 5) .reduce(1, Math::multiplyExact);
9.2.10. map & reduce
map ve reduce ilemleri birlikte kullanm ok fazla tercih edilen iki operasyondur. Buoperasyonlar nemli klan ise, bu iki operasyonun datk sistemler iin ok uygunolmasdr. Piyasada Map & Reduce ilemlerini datk mimarilerde kullanan birok teknolojibulunmaktadr. Tabiki Java 8 ile kullandmz map & reduce ikilisi tek JVM zerinde kotuuiin datk deildir.
rnein;
Hazelcast
Hadoop
MongoDB gibi.
rnek 1; Elimizde Person snf trnden 5 nesne bulunsun. Bu 5 nesne iinden tm kiilerinyalarnn ortalamasn hesaplamak isteyelim. Byle bir senaryo iin map & reduce metodlarnbirlikte tercih edebiliriz.
public class Person { private String name;
map & reduce
55
private Integer age;
// getter, setter ve constructor metodlar}
Person p1 = new Person("Ahmet", 12);Person p2 = new Person("Ali", 20);Person p3 = new Person("Aye", 30);Person p4 = new Person("Murat", 51);Person p5 = new Person("Zeynep", 60);
List personList = Arrays.asList(p1, p2, p3, p4, p5);
personList
.stream()
.map(p -> p.getAge())
.map(Double::valueOf)
.reduce(0, (a, b) -> (a + b)/2);
Person listesiStream nesnesi elde ediliyorNesnenin ya alanna gre mapping yaplyor.Integer Double dnmOrtalamalar hesaplanyor
rnek 2; Person listesinde baz kiilerin ya alanlar null deer iersin. Bu durumda almazamannda nullpointerexception istisnas elde edilecektir. Bu gibi bir durumda filtrelemeyapsn ilemimize ekleyebiliriz.
Person p1 = new Person("Ahmet", 12);Person p2 = new Person("Ali", null);Person p3 = new Person("Aye", 30);Person p4 = new Person("Murat", null);Person p5 = new Person("Zeynep", 60);
List personList = Arrays.asList(p1, p2, p3, p4, p5);
personList .stream() .filter(Objects::nonNull) // Dikkat !! .map(p -> p.getAge()) .map(Double::valueOf)
Parallel Stream
56
.reduce(0, (a, b) -> (a + b)/2);
9.3. Parallel StreamStream arayz iindeki metodlardan ardk iletilmesi gerekmeyenler, istenirse, CPUzerinde paralel olarak koturulabilmektedir. Bu sayede CPU ekirdeklerini tam verimli olarakkullanmak mmkn olmaktadr.
Stream API ierisinde paralel Stream elde etmek olduka kolaydr.
rnein
List ints = Arrays.asList(1, 3, 5, 7, 9, 11, 13, 15);
Stream stream = ints.stream();Stream parallelStream = ints.parallelStream();
Collection#stream() metoduyla ardl (sequential) , Collection#parallelStream() metoduyla daparalel Stream nesnesi elde edilmektedir. Elde edilen paralel Stream nesnesiyle koturulanilemler paralel olarak koabilmektedir.
Ayn zamanda bir ardl Stream nesnesinden paralel Stream nesnesi elde edilebilmektedir.Bunun iin Stream#parallel metodu kullanlmaktadr.
rnein;
List ints = Arrays.asList(1, 3, 5, 7, 9, 11, 13, 15);
Stream stream = ints.stream(); // ArdlStream parallelStream = stream.parallel(); // Paralel
Ayn zamanda bir paralel Stream nesnesinden ardl Stream nesnesi de elde edilebilmektedir.Bunun iin Stream#sequential metodu kullanlmaktadr.
rnein;
List ints = Arrays.asList(1, 3, 5, 7, 9, 11, 13, 15);
Stream parallelStream = ints.parallelStream(); // ParalelStream stream = stream.sequential(); // Ardl
rnek Aada bir dizi saysal ifadeyi filtreleyen, sralayan ve ktlayan bir kod parasgrmekteyiz. Ayrca bu ilemlerin paralel Stream nesnesiyle yaplmak istendiini gryoruz.
Lazy & Eager operasyonlar
57
List ints = Arrays.asList(1, 5, 3, 7, 11, 9, 15, 13);
ints .parallelStream() // Paralel Stream .filter(Objects::nonNull) // null deilse .filter(n -> n > 0) // pozitif say ise .sorted() // srala .forEach(System.out::println); // ktla
Bu rnekte filter ve sorted paralel olarak koturulabilirdir. Fakat forEach metodu doas gereieleri ardk ktlamaldr. te tam da bu admda elimizdeki paralel Stream nesnesi ardlStream nesnesine dntrlmektedir ve ardndan forEach ilemini koturmaktadr.
Yani elimizde paralel Stream nesnesi varsa, bu zincirlemeli ilemin her admnda paralelkoturma yaplaca anlamn tamamaktadr.
9.4. Lazy & Eager operasyonlarLiteratrde Lazy bir ilemin ge, telenmi olarak yaplmas iken, Eager ise yaplacak ileminemir verilir verilmez yaplmasn temsilen kullanlr.
Stream API ierisindeki baz operasyonlar Lazy bazlar ise Eager olarak koturulmaktadr.Lazy davranl olan zincirli grevler, bir Eager operasyona gelene kadar koturulmamaktadr.
List names = Arrays.asList(1,2,3,6,7,8,9);
Stream stream = names .stream() .filter(Objects::nonNull) .filter(n->n%2==1) .map(n->n*2);
rnein yukardaki liste zerinde yaplmak istenen 2 filter ve 1 map ilemi Lazyilemlerdir. Kod paras bu haliyle altrldnda ne bir filtreleme ne de bir dntrmeilemi yaplacaktr. Burada yaplan sadece Stream nesnesini hazrlamaktr. Lazy ilemlergerekmedike ileme konulmamaktadr.
List names = Arrays.asList(1,2,3,6,7,8,9);
Stream stream = names .stream()
.filter(Objects::nonNull)
Lazy & Eager operasyonlar
58
.filter(n->n%2==1)
.map(n->n*2)
stream.forEach(System.out::println); // Dikkat !!
LazyLazyLazyEager
Fakat bu hazrlanan Stream nesnesi, yukardaki gibi bir Eager operasyonla karlarsa,nceki zincirlerde biriken Lazy ilemleri de harekete geirecektir. Yani (4) numaradaki ilem,(1)(2)(3) numaral ilemlerin tetikleyicisi konumundadr.
Tekrar grmek dileiyle..
59
Blm 10. Java 8 ve JVM DilleriJava Sanal Makinesi (JVM), Java 7 ile balayan Da Vinci Machine1 projesiyle, zellikledinamik tipli dilleri JVM zerinde alabilir klmaktadr.
Sun Microsystemin ilk admlarn att bu proje, Oracle firmasyla beraber de nem verilenbir konu olmaya devam etmektedir. JVM ierisinde statik tipli dilleri altrabilmenin birdenfazla amac bulunmaktadr. Bunlar;
JIT (Just in Time) Compiler ile yksek performans sunmak
Birok dilin altrlmasyla JVMi Polyglot2 bir ortam haline getirmek
Farkl dil ve ekosistemleri Java ekosistemine yaknlatrmak
Farkl dil ekosistemlerinin gcn JVMde birletirmek
10.1. JVM Dilleri
Halihazrda Java Sanal Makinesi zerinde birok programlama dili altrlabilmektedir. Budiller Tablo 10.1, JVM Dilleri Tablosunda olduu gibidir;
Tablo 10.1. JVM Dilleri Tablosu
Dil Uygulayc ktphane
Ada JGNAT
BBx BBj is a superset of BBx, PRO/5, and Visual PRO/5.
C C to Java Virtual Machine compilers
Adobe ColdFusion
Railo
CFML
Open BlueDragon
Armed Bear Common LispCommon Lisp
CLforJava
JavaScript Rhino
1 http://openjdk.java.net/projects/mlvm/2 http://en.wikipedia.org/wiki/Polyglot_(computing)
JVM Dilleri
60
Dil Uygulayc ktphane
Nashorn
Free PascalPascal
MIDletPascal
Perl 6 Rakudo Perl 6
JIPrologProlog
TuProlog
Python Jython
REXX NetRexx
Ruby JRuby
Bigloo
Kawa
SISC
Scheme
JScheme
Tcl Jacl
Kaynak: List of JVM languages3
Tablo 10.1, JVM Dilleri Tablosunda listelenen programlama dilleri JVM bnyesindekoturulabilmektedir. Baz diller yorumlama uslyle koturulurken, bazlar ise bayt kodadntrldkten sonra koturulmaktadr. Fakat, JavaScript haricindeki dillere karlk biruygulayc ktphaneyi projenize eklemeniz gerekmektedir.
rnein JVM zerinde Ruby dili ile uygulama gelitirmek istiyoranz, JRuby bamlln Javaprojenize eklemelisiniz.
JRuby Maven Dependency
org.jruby jruby 1.7.16
Dier listeli diller iin de benzer biimde gereken bamllk Java projenize eklenmelidir.
3 http://en.wikipedia.org/wiki/List_of_JVM_languages
Java Scripting API
61
Fakat, JavaScript programlama dili iin olay biraz farkl bir durumda. nk, Java 7Rhino, Java 8 ise Nashorn isimli JavaScript motorlarn gml olarak JVM ierisindebulundurmaktadr. Bu Java ekosisteminin JavaScript diline ne kadar nem verdiini ayrcagstermektedir.
10.2. Java Scripting APIJava programlama dili, tm bu listeli dilleri koturabilmek iin ortak arayzlerin bulunduubir API sunmaktadr. Java Scripting API bileenleri javax.script4 paketi ierisindebulunmaktadr.
javax.script paketi olduka basit arayz ve snflar iermektedir.Bunlardan en nemlisiScriptEngine arayzdr.
10.3. ScriptEngineScriptEngine trnden nesneler, ScriptEngineManager#getEngineByName metoduzerinden esiz bir takma isim ile elde edilmektedir. Bu nesneler ile, String trndenkod bloklar koturulabilmekte, ayrca Java ile iletiim kurulabilmektedir. rnein, NashornJavaScript motoru iin "nashorn" veya "rhino" takma adlar, Ruby iin ise "jruby"takma ad kullanlmaktadr.
rnein;
...ScriptEngineManager engineManager = new ScriptEngineManager();
ScriptEngine engine = engineManager.getEngineByName("nashorn");
ScriptEngine engine = engineManager.getEngineByName("rhino");
ScriptEngine engine = engineManager.getEngineByName("jruby");
ScriptEngine engine = engineManager.getEngineByName("jython"); ...
Java 8 iin JavaScript motoruJava 7 iin JavaScript motoruRuby iin JRuby motoruPython iin Jython motoru
4 http://docs.oracle.com/javase/8/docs/api/javax/script/package-summary.html
Nashorn JavaScript Motoru
62
10.4. Nashorn JavaScript MotoruNashorn, Java 8 iin zel olarak sfrdan gelitirilen bir JavaScript motorudur. Nashorn, RhinoJavaScript motoruna gre 5 kat daha fazla performans sunmaktadr.
Nashorn JavaScript motoru EcmaScript 5 standardn desteklemekte ve tm testlerinibaaryla gemi bulunmaktadr.
JVM dillerinden Java Scripting API destekleyenler, ScriptEngine#eval metodu ile kodbloklarn koturma imkan elde etmektedir. Bu sayede ortak arayz bileenleri zerinden Javaharici diller JVM zerinde koturulabilmektedir.
Nashorn Engine rnei
ScriptEngineManager engineManager = new ScriptEngineManager();
ScriptEngine engine = engineManager.getEngineByName("nashorn");
engine.eval("function topla(a,b){ return a + b; }");
String sonuc=(String)engine.eval(topla(3,5);); System.out.println(sonuc); // 8
Nashorn Engine elde ediliyor.topla isimli JavaScript fonksiyonu tanmlanyor.topla fonksiyonu Nashorn ile koturuluyor, ve sonucu elde ediliyor.
Siz de Java Scripting API destekleyen dier dilleri JVM ekosisteminde koturabilirsiniz.
Tekrar grmek dileiyle..
63
Blm 11. Java 8 Optional YeniliiBir Java gelitiricisinin korkulu ryas NullPointerException istisnalaryla uramaktr.null deer ile karlamak, ona kar nlem almak herzaman iin can skc olmutur. Bu canskcl ortadan kaldrmak iin Java 8 ierisinde Optional snf getirilmitir. Optionalyaps daha evvelden farkl dil ortamlarnda bulunan bir zelliktir.
Optional trnden nesneler, null olma ihtimali olan alanlar kolay ynetmek iinoluturulmutur.
11.1. Optional Oluturmak
Bir Optional nesnesi, Optional snfnn eitli statik metodlaryla oluturulmaktadr.Bunlar empty , of ve ofNullable 'dir.
emptyTaze bir Optional nesnesi oluturur.
ofBir nesneyi Optinal ile sarmalar. Parametre olarak null deer kabul etmez.
ofNullableBir nesneyi Optinal ile sarmalar. Parametre olarak null deer kabul eder.
rnein
Optional empty = Optional.empty();
Optional of = Optional.of("Merhaba Dnya");
Optional ofNull = Optional.of(null);
Optional ofNullable = Optional.ofNullable(null);
Deer iermeyen OptString trnden deer ieren OptOptional#of null kabul etmez. stisna frlatr.Optional#ofNullable null kabul eder. stisna frlatmaz.
#ifPresent - Varsayap, yoksa yapma
64
11.2. #ifPresent - Varsa yap, yoksa yapma
Eer bir Optional ierisinde sadece veri varsa ( null deilse) bir iin yaplmas isteniyorsa#ifPresent metodu kullanlabilir. #ifPresent metodu Consumer fonksiyonelarayz trnden bir nesne kabul etmektedir.
rnein bir saynn karesini almaya alalm. Kullanlan deiken null deerini referansediyorsa NullPointerException istisnas alnacaktr.
Integer numara = null;
Double karesi = Math.pow(numara , 2);
System.out.println("Sonu: " + karesi);
Exception in thread "main" java.lang.NullPointerExceptionBu istisna iin if deyimiyle kar nlem alnabilir.
Integer numara = null;
if(numara != null) {
Double karesi = Math.pow(numara , 2);
System.out.println("Sonu: " + karesi);
}
Fakat if deyimiyle birlikte ! , == , != ifadelerini kullanmak akc bir gelitirimdeneyimi sunmaz. Ayrca bu durum hata yaplmasna daha aktr. Bunun yerineOptional#ifPresent metodunu kullanabiliriz.
Integer numara = null;
Optional opt = Optional.ofNullable(numara);
opt.ifPresent(num -> { Double karesi = Math.pow(num , 2); System.out.println("Sonu: " + karesi);});
#map - Dntrme
65
11.3. #map - DntrmeOptional nesnelerinin sarmalad veriler zerinde dntrm yaplabilmektedir. Birnceki rnei bu ekilde yeniden yazabiliriz.
Integer numara = null;
Optional opt = Optional.ofNullable(numara);
opt .map(num->Math.pow(num,2)) .ifPresent(System.out::println);
11.4. #filter - FiltrelemeOptional nesnelerinin sarmalad veriler zerinde szme ilemi de yaplabilmektedir.
rnein aadaki kod paras yerine;
String message = null;
if (message != null) if (message.length() > 5) System.out.println(message);
Aadaki Optional karln kullanabiliriz.
String message = null;Optional opt = Optional.ofNullable(message);
opt .filter(m -> m.length() > 5) .ifPresent(System.out::println);
11.5. #orElse - Varsa al, yoksa bunu alorElse metodu daha ok ternary ( l ) art ihtiyac olduu durumlarda ihtiya duyulabilir.Daha akc bir gelitirim deneyimi sunar.
numara null deilse numaray dndr, null ise 0 dndr.
Integer numara = null;
#orElseGet - Varsaal, yoksa ret
66
int result = (numara != null) ? numara : 0;
Yukardaki l art orElse ile birlikte kullanabiliriz.
Integer numara = null;
Optional opt = Optional.ofNullable(numara);
int result = opt.orElse(0);
11.6. #orElseGet - Varsa al, yoksa retBu metod orElse metoduna ok benzer, fakat orElseGet metod parametresi olarakSupplier fonksiyonel arayz trnden nesne kabul eder.
List names = Arrays.asList("Ali","Veli","Selami");
Optional opt = Optional.ofNullable(names);
names = opt.orElseGet(()-> new ArrayList());
names = opt.orElseGet(ArrayList::new);
Lambda ileMetod referans ile
11.7. #orElseThrow - Varsa al, yoksa frlatOptional nesnesi bir deeri ieriyorsa ( null olmayan) o deeri dndrr, null ise desalanan istisna nesnesini frlatr. orElseThrow metodu Supplier trnden bir nesnekabul eder.
Integer numara = null;
Optional opt = Optional.ofNullable(numara);
int result = opt.orElseThrow(RuntimeException::new);
Varsa dndrr, yoksa yeni bir RuntimeException istisnas frlatr.
#orElseThrow -Varsa al, yoksa frlat
67
Java 8 yeniliklerini Java 8 Ebook1 ile renebilirsiniz.
Tekrar grmek dileiyle.
1 http://kodcu.com/java-8-ebook/
68
69
Blm 12. Java 8 EmbeddedJava 8 Embedded, Java alma ortamn (JRE), snrl bellek imkanlarna sahip gmlcihazlarda, az bellek tketimli olarak sunmay amalayan dncenin rndr.
Java alma ortam, farkl ilemci ailesi ve farkl iletim sistemi ailelerine gre ayrcahazrland iin platform bamszln sunmaktadr. rnein bugn x86 mimarili bir ilemciiin Windows , Mac ve Linux trevi iletim sistemlerinde hem alma ortamn hemgelitirme ortamn kullanabiliyoruz. Ha keza, ARM 6/7 ilemci ailesine sahip makinelerdeJava alma (JRE) ve gelitirme ortamn (JDK) kullanabiliyoruz.
Gml sistemlerde ARM mimarili ilemciler ok fazla tercih ediliyor. rnein elinizdeki aklltelefonun ARM ailesinden bir ilemci olma olasl ok ok yksek. Poplerlii olduka yksekolan bir gml cihaz Raspberry PI' de ARM ailesinden bir ilemci kullanyor.
ekil 12.1. Raspberry PI
Gml cihazlarn kendine has snrllklar bulunuyor. Bu snrllklarn en banda ise belleksnrll geliyor. ARM ilemci ailesine gre yaplandrlm full bir JRE, disk ortamnda yaklakolarak 47 mb yer tutuyor. 47 MB gze ok gzkmeyebilir, ama, rnein 64 MB bir belleesahip gml cihaz iin 47 MB ok fazla! te tam da bu noktada Java 8 Embedded devreyegiriyor.
Java 8 Embedded, Java alma ortamn (JRE), gml cihazlar iin ksmi modlerlik ileboyut olarak drmeyi amalamaktadr. Bu amala Java 8 Embedded gelitirim ihtiyalarnagre 3 tip JRE profili sunmaktadr. Bir de full profili katarsak toplamda 4 profil var.
70
Java 8 Embedded, compact 1 , compact 2 ve compact 3 profillerini sunmaktadr.Bu profillerde, en ok ihtiya duyulabilecek spesifik Java paketleri gruplandrlarak boyutbakmndan klme salanmaktadr.
Buna ilaveten, standart bir JRE iin iki JVM modu bulunmaktadr. Bunlar client veserver mode dur. Bu iki seenekte alma ortamna gre JIT Compiler bazndaayrtrma yaplmaktadr. Java 8 Embedded iin ise varsaylan olarak client ve servermodu haricinde minimal modu gelmektedir. minimal modda bellek tketimi minimizeedilmektedir. Fakat bu modda azami %5 'lik bir performans dm makul karlanmaktadr.
Birbirini ierir biimde yaplandrlan Compact profiller, sk tercih edilecei dnlenpaketler baznda gruplandrlmtr. Bu gruplamay aadaki ekilden grebilmekteyiz.
ekil 12.2. Full JRE > compact 3 > compact 2 > compact 1
rnein gml sisteminizde en temel Java paketlerini kullanacaksanz compact 1 profilinisemek size avantaj salayacaktr. compact 1 profilinde hazrlanan JRE yaklak 9.5MBdir. Profiller aras boyutsal kyaslamaya dair grafii aada gryoruz.
JavaFX Extension
71
ekil 12.3. Compact profile karlatrmalar
12.1. JavaFX Extension
JavaFX eklentisi kullanldnda, gml cihaznzda JavaFX kullanmak iin gerekli paketlerEmbedded JRE iine dahil edilmektedir. Elbette, oluan ktlarn boyutlar artmaktadr(Yaklak 10M kadar daha).
> jrecreate -p compact1 -x fx:controls --dest ejdk-compact1-javafx
> jrecreate -p compact2 -x fx:controls --dest ejdk-compact2-javafx
> jrecreate -p compact3 -x fx:controls --dest ejdk-compact3-javafx
ejdk-compact1-javafx dizininde compact1 profilli JavaFX ieren JRE oluturur.ejdk-compact2-javafx dizininde compact2 profilli JavaFX ieren JRE oluturur.ejdk-compact3-javafx dizininde compact3 profilli JavaFX ieren JRE oluturur.
Nashorn Extension
72
ekil 12.4. Compact profile karlatrmalar (JavaFX dahil)
12.2. Nashorn ExtensionJava 8 ile birlikte gelen Nashorn JavaScript motoru, bir eklenti olarak rettiiniz ejre iinedahil edilebilmektedir. Bu sayee JVM iinde JavaScript dilinde yazlan uygulamalar altrmaimkan elde edilmektedir. Nashorn eklentisi ejre ktsna yaklak 1MB ilave etmektedir.
> jrecreate -p compact1 -x nashorn --dest ejdk-compact1-nashorn
> jrecreate -p compact2 -x nashorn --dest ejdk-compact2-nashorn
> jrecreate -p compact3 -x nashorn --dest ejdk-compact3-nashorn
ejdk-compact1-nashorn dizininde compact1 profilli Nashorn ieren JREoluturur.ejdk-compact2-nashorn dizininde compact2 profilli Nashorn ieren JREoluturur.ejdk-compact3-nashorn dizininde compact3 profilli Nashorn ieren JREoluturur.
-x parametresiyle JavaFX eklentisi belirtildiinde, JavaFX retilenJRE iine dahil edilmektedir. -x parametresi fx:controls ,sunec , sunpkcs11 , locales , charsets , nashorn deerlerinikabul etmektedir. Birden fazlasn ayn anda kullanmak iin ( , )kullanlabilmektedir.
12.3. Java 8 ME vs Java 8 EmbeddedJava Me ile Java Embeddedin birbirine kartrlmas olduka olas. Java ME, gmlcihazlarda Java sanal makinesinin (JVM) ok ok kk bellek tketerek almasna olanak
Java 8 ME vsJava 8 Embedded
73
salayan zel bir Java alma ortamdr. Java 8 Me ile gml cihazlarn donanmsalbirimlerini kontrol etmek mmkndr. rnein bir gml cihazn giri/k pinlerini,Watchdog Timer gibi bileenlerini kullanabilirsiniz. Java ME iinde bunlar kullanabilmek iinzel paket ve snflar yer almaktadr.
Tekrar grmek dileiyle.
74
75
Blm 13. CompletableFuture ileAsenkron ProgramlamaCompletableFuture snf, Java 8 ierisinde asenkron operasyonlar iin zelletirilen birsnftr. Java ortamnda Java SE ve Java EE teknolojilerinde bir ok asenkron programlamaimkan halihazrda gelitiricilere sunulmaktadr. CompletableFuture snf ise, asenkronprogramla ihtiyalarna ok daha genel zmler getirmektedir.
13.1. Syncronous vs. AsyncronousEer bir uygulamann aknda, bir grevin balamas dier grevin bitiine bal ise,buna senkron programlama; Eer bir grevin balamas dier grevin balamasna engelolmuyorsa da asenkron programlama kavramlar ortaya kmaktadr. Java programlama diliasenkron programlamaya ou noktada imkan salamakla birlikte, dilin genel yatknl oudil gibi senkron programlama ynndedir. Fakat, rnein JavaScript gibi bir dili incelediinizde,asenkronitinin dilin diyaznn ne derece etkilediini gzlemleyebilirsiniz.
rnein, elimizde fetchFromDatabase ve saveFiles metodlar olduunu varsayalm.lk metodun koturulma sresi 5, dierinin ise 3 saniye alyor olsun.
private List fetchFromDatabase(){ ... Thread.sleep(5000); ...}
private List readFiles(){ ... Thread.sleep(3000); ...
}
imdi bu iki metodu peisra koturalm.
fetchFromDatabase();readFiles();
Bu iki grevin tamamlanma sresi ne kadar olacak?
Syncronous vs. Asyncronous
76
Cevap: Math.sum(5,3) = 8
Java dilinin genel doas gerei bu iki i srasyla iletilecektir. Fakat dikkat edilirse, yaplan ikii birbirinden tamamen bamszdr. Biri DBden veri ekiyor, dieri ise dosyalama sistemindendosya okuyor. Dolaysyla, bu ilerden birinin balamas iin dier iin tamamlanmasbeklenmek zorunda deil.
Bu iki metodun asenkron olarak almas iin geleneksel okilemcikli programlama ileharici asenkron i kollar oluturulabilir. Fakat, burada geleneksel yntemlerin dndaCompletableFuture nesnesi zerinden gitmekte fayda gryorum.
public class CompletableFuture implements Future, CompletionStage { ...}
CompletableFuture snf Future ve CompletionStage arayzleri trnden jenerikbir snf. CompletableFuture trnden nesneler, nesnenin yaplandrcs zerinden veyaCompletableFuture 'nin eitli statik metodlaryla oluturulabilmektedir.
CompletableFuture ile doas senkron komak olan bir ii, asenkron koar halegetirebilirsiniz. Aslnda yaplan i, senkron koan iin arka plana itilerek koturulmas vemevcut program aknn kesintiye uratlmamasdr. CompletableFuture nesneleri,ekstra olarak tanmlanmad srece tek bir ForkJoin Thread havuzu ile ilerini asenkronolarak arka planda koturmaktadr.
imdi yukardaki senkron rnei asenkron hale getirelim. Bunun iinCompletableFuture#runAsync metodu kullanlabilir.
public static CompletableFuture runAsync(Runnable runnable) { ... return f;}
CompletableFuture#runAsync metodu Runnable trnden bir grev snf kabuletmektedir, arndan CompletableFuture trnden bir nesne dndrmektedir. Parametre olarakiletilen Runnable nesnesi, arkaplanda asenkron olarak koturulmaktadr.
Runnable arayz tek bir soyut metoda sahip olduu iin, Lambdafonksiyonu olarak temsil edilebilir. () { }
CompletableFuture#allOf
77
CompletableFuture futured1 = CompletableFuture.runAsync(() -> {
fetchFromDatabase();
});
CompletableFuture futured2 = CompletableFuture.runAsync(() -> {
saveToFile();
});
futured1.join();
futured2.join();
Yukardaki (1) ve (2) numaral iler bu noktadan sonra arkaplanda ForkJoin thread havuzuiinde koturulmu olacak. Bylece (2) numaral i, (1) numaral i koturulmaya balatldktanhemen sonra almaya balayacak, dierinin ie koyulmasn bloke etmeyecek.
Peki imdi bu iki asenkron grevin tamamlanma sresi ne kadar olacak?Cevap: Math.max(5,3) = 5
Burada iki i birden hemen hemen ayn anda balayaca iin, iki iin toplamda tamamlanmasresi yaklak olarak en fazla sren grev kadar olacaktr.
CompletableFuture#join metodu, asenkron olarak koturulangrev tamamlanana kadar, uygulama aknn mevcut satrda askdakalmasn salar. Yani (3) ve (4) satrlarndan sonraki satrlarda,yukardaki iki iin birden tamamlanm olduunu garanti edebiliriz.
13.2. CompletableFuture#allOfBirden fazla CompletableFuture nesnesini birletirir. Ancak herbir i birden tamamlandnda,CompletableFuture nesnesi tamamland bilgisine sahip olur.
public static CompletableFuture allOf(CompletableFuture... cfs) {
...
}
rnein;
CompletableFuture#anyOf
78
CompletableFuture future1 = CompletableFuture.runAsync(() -> { ... Thread.sleep(5000); ...
System.out.println("lk grev tamamland..");});
CompletableFuture future2 = CompletableFuture.runAsync(() -> { ... Thread.sleep(15000); ...
System.out.println("Dier grev tamamland..");});
CompletableFuture allOf = CompletableFuture.allOf(future1, future2);
System.out.println("Bir arada iki derede.");
allOf.join();
System.out.println("Bitti.");
Yukarda iki tane asenkron i koturulmaktadr. Bir tanesi 5, dieri ise 15 saniye srmektedir.Eer asenkron koan uygulama aknda, bu iki i bitene kadar bir noktada beklemekistiyorsak, CompletableFuture#allOf dan faydalanabiliriz. Uygulama aknn askdabekletilmesi ise CompletableFuture#join metodu ile salanmaktadr.
kt
Bir arada iki derede. // 0. saniyedelk grev tamamland.. // 5. saniyedeDier grev tamamland.. // 15. saniyedeBitti. // 15. saniyede
13.3. CompletableFuture#anyOfBirden fazla CompletableFuture nesnesini birletirir. Herhangi bir grev tamamlandnda,CompletableFuture nesnesi tamamland bilgisine sahip olur.
rnein;
CompletableFuture future1 = CompletableFuture.runAsync(() -> {
CompletableFuture#supplyAsync
79
... Thread.sleep(5000); ...
System.out.println("lk grev tamamland..");});
CompletableFuture future2 = CompletableFuture.runAsync(() -> { ... Thread.sleep(15000); ...
System.out.println("Dier grev tamamland..");});
CompletableFuture anyOf = CompletableFuture.anyOf(future1, future2);
System.out.println("Bir arada iki d