├── images ├── ejdk.png ├── wifi.png ├── cover.png ├── anod-p5.png ├── ejdk-bin.png ├── breadboard.png ├── compact-vss.png ├── direnc-led.png ├── starter-kit.png ├── device-manager.png ├── gnuwin32-bin.png ├── javame-step-1.png ├── javame-step-2.png ├── javame-step-3.png ├── permission-1.png ├── permission-2.png ├── raspberry-pi.png ├── compact-profiles.png ├── ejdk-bin-output.png ├── raspberry-javame.png ├── breadboard-inside.png ├── compact-profiles-fx.png ├── device-manager-icon.png ├── add-device-connection.png ├── gpio-extension-cable.png ├── embedded-external-device.png ├── gpio-extension-breadboard.png └── javame8-sdk-plugin-install.png ├── book.asc ├── README.asc ├── chapter-02.asc ├── chapter-01.asc ├── chapter-05.asc ├── chapter-12.asc ├── chapter-10.asc ├── chapter-11.asc ├── chapter-04.asc ├── chapter-07.asc ├── chapter-03.asc ├── chapter-06.asc ├── chapter-09.asc ├── chapter-13.asc ├── chapter-14.asc └── chapter-08.asc /images/ejdk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/ejdk.png -------------------------------------------------------------------------------- /images/wifi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/wifi.png -------------------------------------------------------------------------------- /images/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/cover.png -------------------------------------------------------------------------------- /images/anod-p5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/anod-p5.png -------------------------------------------------------------------------------- /images/ejdk-bin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/ejdk-bin.png -------------------------------------------------------------------------------- /images/breadboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/breadboard.png -------------------------------------------------------------------------------- /images/compact-vss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/compact-vss.png -------------------------------------------------------------------------------- /images/direnc-led.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/direnc-led.png -------------------------------------------------------------------------------- /images/starter-kit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/starter-kit.png -------------------------------------------------------------------------------- /images/device-manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/device-manager.png -------------------------------------------------------------------------------- /images/gnuwin32-bin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/gnuwin32-bin.png -------------------------------------------------------------------------------- /images/javame-step-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/javame-step-1.png -------------------------------------------------------------------------------- /images/javame-step-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/javame-step-2.png -------------------------------------------------------------------------------- /images/javame-step-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/javame-step-3.png -------------------------------------------------------------------------------- /images/permission-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/permission-1.png -------------------------------------------------------------------------------- /images/permission-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/permission-2.png -------------------------------------------------------------------------------- /images/raspberry-pi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/raspberry-pi.png -------------------------------------------------------------------------------- /images/compact-profiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/compact-profiles.png -------------------------------------------------------------------------------- /images/ejdk-bin-output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/ejdk-bin-output.png -------------------------------------------------------------------------------- /images/raspberry-javame.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/raspberry-javame.png -------------------------------------------------------------------------------- /images/breadboard-inside.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/breadboard-inside.png -------------------------------------------------------------------------------- /images/compact-profiles-fx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/compact-profiles-fx.png -------------------------------------------------------------------------------- /images/device-manager-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/device-manager-icon.png -------------------------------------------------------------------------------- /images/add-device-connection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/add-device-connection.png -------------------------------------------------------------------------------- /images/gpio-extension-cable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/gpio-extension-cable.png -------------------------------------------------------------------------------- /images/embedded-external-device.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/embedded-external-device.png -------------------------------------------------------------------------------- /images/gpio-extension-breadboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/gpio-extension-breadboard.png -------------------------------------------------------------------------------- /images/javame8-sdk-plugin-install.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rahmanusta/java8-ebook/HEAD/images/javame8-sdk-plugin-install.png -------------------------------------------------------------------------------- /book.asc: -------------------------------------------------------------------------------- 1 | = Java 8 Ebook 2 | Rahman Usta 3 | :email: rahmanusta@kodcu.com 4 | :revdate: 12-10-2014 5 | :doctype: book 6 | :encoding: utf-8 7 | :lang: tr 8 | :toc: 9 | :numbered: 10 | 11 | [preface] 12 | == Önsöz 13 | 14 | Java 8 ve yeniliklerini içeren bu kitap ile, Java programlama dilinin en yeni özelliklerini öğrenebilirsiniz. 15 | 16 | Java 8 Ebook http://kodcu.com[kodcu.com] 'da http://kodcu.com/author/rahmanusta/[Rahman Usta] tarafından kaleme alınan Java 8 yazılarını içermektedir. 17 | 18 | include::chapter-01.asc[] 19 | 20 | include::chapter-02.asc[] 21 | 22 | include::chapter-03.asc[] 23 | 24 | include::chapter-04.asc[] 25 | 26 | include::chapter-05.asc[] 27 | 28 | include::chapter-06.asc[] 29 | 30 | include::chapter-07.asc[] 31 | 32 | include::chapter-09.asc[] 33 | 34 | include::chapter-08.asc[] 35 | 36 | include::chapter-10.asc[] 37 | 38 | include::chapter-11.asc[] 39 | 40 | include::chapter-12.asc[] 41 | 42 | include::chapter-13.asc[] 43 | 44 | include::chapter-14.asc[] 45 | 46 | [appendix] 47 | == Bu kitap nasıl yazıldı? 48 | 49 | *Java 8 Ebook* kitabı açık kaynak kodlu http://asciidocfx.com/[Asciidoc Fx] kitap editörü kullanılarak, http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/[Asciidoc işaretleme dili] ile yazılmıştır. -------------------------------------------------------------------------------- /README.asc: -------------------------------------------------------------------------------- 1 | = Java 8 Ebook 2 | Rahman Usta 3 | :email: rahmanusta@kodcu.com 4 | :revdate: 12-10-2014 5 | :doctype: book 6 | :encoding: utf-8 7 | :lang: tr 8 | :toc: 9 | :numbered: 10 | 11 | [preface] 12 | == Önsöz 13 | 14 | Java 8 ve yeniliklerini içeren bu kitap ile, Java programlama dilinin en yeni özelliklerini öğrenebilirsiniz. 15 | 16 | Kitabı aynı zamanda PDF, Epub ve Mobi formatlarında edinerek Mobil, masaüstü ve Kindle ortamlarında okuyabilirsiniz. http://kodcu.com/java-8-ebook[Java 8 Ebook] 17 | 18 | image::images/cover.png[align="center"] 19 | 20 | [width="100%",options="",cols="5"] 21 | |==================== 22 | |++++++++++++++++++++++++ 23 | include::chapter-01.asc[] 24 | ++++++++++++++++++++++++ 25 | | ++++++++++++++++++++++++ 26 | include::chapter-02.asc[] 27 | ++++++++++++++++++++++++ 28 | | ++++++++++++++++++++++++ 29 | include::chapter-03.asc[] 30 | ++++++++++++++++++++++++ 31 | | ++++++++++++++++++++++++ 32 | include::chapter-04.asc[] 33 | ++++++++++++++++++++++++ 34 | | ++++++++++++++++++++++++ 35 | include::chapter-05.asc[] 36 | ++++++++++++++++++++++++ 37 | | ++++++++++++++++++++++++ 38 | include::chapter-06.asc[] 39 | ++++++++++++++++++++++++ 40 | |++++++++++++++++++++++++ 41 | include::chapter-07.asc[] 42 | ++++++++++++++++++++++++ 43 | | ++++++++++++++++++++++++ 44 | include::chapter-08.asc[] 45 | ++++++++++++++++++++++++ 46 | | ++++++++++++++++++++++++ 47 | include::chapter-09.asc[] 48 | ++++++++++++++++++++++++ 49 | | ++++++++++++++++++++++++ 50 | include::chapter-10.asc[] 51 | ++++++++++++++++++++++++ 52 | | ++++++++++++++++++++++++ 53 | include::chapter-11.asc[] 54 | ++++++++++++++++++++++++ 55 | | ++++++++++++++++++++++++ 56 | include::chapter-12.asc[] 57 | ++++++++++++++++++++++++ 58 | | ++++++++++++++++++++++++ 59 | include::chapter-13.asc[] 60 | ++++++++++++++++++++++++ 61 | | ++++++++++++++++++++++++ 62 | include::chapter-14.asc[] 63 | ++++++++++++++++++++++++ 64 | | 65 | |==================== 66 | 67 | [appendix] 68 | == Nasıl destek olurum? 69 | 70 | Kitaba yeni bölümler ekleyebilir ve var olan eksiklikleri gidermekte yardımcı olabilirsiniz. Bu sayede açık ve paylaşımcı olarak özgün kaynaklar üretmiş oluruz. 71 | 72 | [appendix] 73 | == Böyle bir kitabı nasıl yazarım? 74 | 75 | *Java 8 Ebook* kitabı açık kaynak kodlu http://asciidocfx.com/[Asciidoc Fx] kitap editörü kullanılarak, http://asciidoctor.org/docs/asciidoc-syntax-quick-reference/[Asciidoc işaretleme dili] ile yazılmıştır. Aşağıdaki 2 videoyu seyrederek siz de AsciidocFX kullanmaya başlayabilirsiniz. 76 | 77 | http://www.youtube.com/watch?v=2goMtz_vdtM[Hızlı başlangıç] + 78 | http://www.youtube.com/watch?v=I8zCklX3eTk[Detaylı başlangıç] 79 | 80 | kodcu.com olarak bu süreçte size yardımcı olmaktan mutluluk duyarız. 81 | 82 | Teşekkürler + 83 | *Kodcu.com ekibi*. 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /chapter-02.asc: -------------------------------------------------------------------------------- 1 | == Lambda ifadeleri ve Fonksiyonel arayüzler 2 | 3 | Merhaba arkadaşlar; 4 | 5 | Bugün sizlerle fonksiyonel arayüzlerden (`Functional Interfaces`) ve Lambda ifadeleri (Lambda Expressions) ile olan ilişkisinden basetmek istiyorum. 6 | 7 | === Functional Interfaces 8 | 9 | Tek bir soyut metodu bulunan arayüzlere fonksiyonel arayüz denir. İki veya üç değil, yalnızca bir tane soyut metodu olmalı. Peki neden `“1”` dersek sebebinin Lambda ifadelerine dayandığını söylemek isterim. 10 | 11 | *Örneğin;* 12 | 13 | Şöyle bir Lambda ifademiz olsun; 14 | 15 | [source,java] 16 | ---- 17 | fn(x,y) -> 2*x + y 18 | ---- 19 | 20 | Bu Labmda deyimini örneğin Javascript gibi bir dil ile temsil etmek isteseydik şöyle yazabilirdik; 21 | 22 | [source,java] 23 | ---- 24 | function(x , y) { 25 | 26 | return 2*x+y; 27 | 28 | } 29 | ---- 30 | 31 | *Peki fn(x,y) -> 2*x + y Lambda ifadesini Java programlama dilinde nasıl yazabiliriz?* 32 | 33 | Java 8 geliştirilirken, geliştirim takımı kendilerine bu soruyu sormuş ve yanıt olarak fonksiyonel arayüzler kullanarak ihtiyacı karşılamışlar. 34 | 35 | Şöyle ki; Bir Lambda ifadesi, Java derleyicisi tarafından, bir Java arayüzünün (tek bir soyut metodu olmalı) nesnel karşılığına (implementation) dönüştürülmektedir. 36 | 37 | Örneğin, `fn(x,y) -> 2*x + y` Lambda ifadesi, aşağıdaki fonksiyonel arayüze dönüştürülebilirdir. Çünkü fonksiyon x ve y adında iki parametre almakta ve `2*x + y` ile tek bir değer döndürmektedir. Tabi burada `x` ve `y` ’ nin tipleri ne? dersek, herhangi bir matematiksel tip olabilir. Biz burada sabit bir tip (int gibi) verebilir, veya jenerik tiplemeler de yapabiliriz. Fakat şu anlık bununla yetinelim. 38 | 39 | [source,java] 40 | ---- 41 | @FunctionalInterface // Opsiyonel 42 | interface Foo{ 43 | 44 | int apply(int x, int y); 45 | 46 | } 47 | ---- 48 | 49 | Şimdi bu Lamda ifadesini uygulamamızda kullanalım. 50 | 51 | *Örnek 1:* 52 | 53 | Lambda ifadeleri atama sırasında kullanılabilir. 54 | 55 | [source,java] 56 | ---- 57 | Foo foo = (x,y) -> (2*x+y); 58 | 59 | int sonuc = foo.apply(3,4); 60 | 61 | System.out.println("Sonuç: "+sonuc); // Çıktı: 10 62 | 63 | // veya 64 | 65 | Foo foo = (x, y) -> Math.pow(x,y); 66 | 67 | int sonuc = foo.apply(3,2); 68 | 69 | System.out.println("Sonuç: "+sonuc); // Çıktı: 3*3 = 9 70 | ---- 71 | 72 | *Örnek 2:* 73 | 74 | Lambda ifadeleri, metod parametrelerinde de tanımlanabilir. 75 | 76 | [source,java] 77 | ---- 78 | class Bar{ 79 | 80 | public int calculate(Foo foo, int x, int y){ 81 | return foo.apply(x,y); 82 | } 83 | } 84 | 85 | Bar bar = new Bar(); 86 | 87 | int sonuc = bar.calculate( (x,y) -> (2*x+y) , 3, 4 ); 88 | 89 | System.out.println("Sonuç: "+sonuc); // Çıktı: 10 90 | ---- 91 | 92 | Java programlama dilinde fonksiyon ifadesi pek kullanılmaz, onun yerine metod ifadesi kullanılır. Java metodları tek başına birer eleman değildir, diğer bir dil elemanının (sınıf, enum, interface ..) dahilinde tanımlanırlar. Javascript gibi dillerde ise fonksiyonlar tek başına birer elemandır, diğer bir dil elemanının içinde olmak zorunluluğu yoktur. Bu sebeple Java ortamında, bir Lambda ifadesinden bir fonksiyona/metoda/iş birimine dönüşüm için fonksiyonel arayüzler kullanılmaktadır. 93 | 94 | Tekrar görüşmek dileğiyle.. -------------------------------------------------------------------------------- /chapter-01.asc: -------------------------------------------------------------------------------- 1 | == Lambda Expression nedir? Nasıl kullanırım? 2 | 3 | Merhaba arkadaşlar; 4 | 5 | Bugün sizlerle Java 8 (Project Lambda) ile Java ortamına katılan Lambda ifadelerinden (Lambda expression) bahsetmek istiyorum. 6 | 7 | === Lambda nedir? 8 | 9 | Programlama dili çerçevesinde Lambda, anonim tekil görevler olarak değerlendirilebilir. Lambda deyimleri (Lambda fonksiyonları da denebilir), referans verilebilir ve tekrar tekrar kullanılabilirdir. Genel kullanım açısından Lambda fonksiyonları, diğer bir fonksiyona argüman olarak iletilebilirdir. Böylece, bir tarafta tanımlanan iş birimi, diğer bir iş biriminde koşturulabilir olmaktadır. Burada dikkat çekilecek unsur, bir iş biriminin diğer bir uygulama birimine referans olarak eriştirilebilirliğidir. 10 | 11 | === Javascript ile Lambda – Basit Giriş 12 | 13 | Javascript dilinde `Array` sınıfının prototype alanında `forEach` isimli bir iş birimi (fonksiyon) bulunmaktadır. `forEach` fonksiyonu, parametre olarak bir anonim Javascript fonksiyonunu kabul etmektedir. `forEach` fonksiyonuna, parametre olarak tanımlanan anonim fonksiyon, `forEach` fonksiyonu içerisinde koşturulmaktadır. Bu sayede iş mantığı, diğer fonksiyona paslanmış olmaktadır. 14 | 15 | *Örnek 1:* 16 | 17 | [source,java] 18 | ---- 19 | var dizi = [1,2,3,4,5]; // Bir javascript dizisi 20 | 21 | // Anonim fonksiyon her bir elemanı çıktılıyor. 22 | dizi.forEach(function(e){ // (1) 23 | console.log("Eleman: ",e); 24 | }); 25 | 26 | ---- 27 | 28 | Yukarıda *(1)* numaralı kısımdaki anonim fonksiyon yani lambda fonksiyonu, forEach metodu içerisinde koşturulmaktadır. forEach metodu içerisindeki benzer yaklaşımı, kendi fonksiyonumuz ile oluşturalım. 29 | 30 | [source,java] 31 | ---- 32 | var fonk= function(a,b,callback){ 33 | // Lambda fonksiyonu "callback" burada koşturulur. 34 | return callback(a,b)*2; // (2) 35 | } 36 | 37 | var result = fonk(2,3,function(a,b){ // (1) 38 | // Bu Lambda fonksiyonu 2 argümanı toplar. 39 | return a+b; 40 | }); 41 | 42 | console.log("Sonuç ..: ",result); // Sonuç : (2+3)*2 = 10 43 | 44 | ---- 45 | 46 | Tekrar ederek, Lambda fonksiyonları için referans verilebilir iş birimleri denebilir. Bu yaklaşım bir çok programlama dilinde farklı biçimlerde yer alabilir, anlaşılabilirlik açısından ilk önce Javascript örneği vermeyi tercih ettim. 47 | 48 | === Lambda Java 8 öncesinde nasıldı? 49 | 50 | Lambda birimleri (referans verilebilir iş birimleri), Java 8 evvelinde anonim sınıflar ile tanımlanabilmekteydi. Örnek 2’nin benzeri Java 8 evvelinde nasıl yazılıyordu? 51 | 52 | Öncelikle bir iş birimi tipi gerekli, bu iş birimi 2 argüman kabul etmeli ve bir değer döndürmelidir. İş mantığı anonim olarak tanımlanacağı için, abstract sınıflar veya arayüzler kullanılabilir. 53 | 54 | *Örnek 3* 55 | 56 | [source,java] 57 | ---- 58 | public interface Anonim{ 59 | public int call(int a, int b); 60 | } 61 | ---- 62 | 63 | Anonim arayüz sözleşmesi, int türünden 2 değer alır ve bir int değer döndürür. Dikkat ederseniz sadece sözleşmenin maddesi tanımlandı, iş mantığı anonim olarak geliştirici tarafından tanımlanacak. 64 | 65 | [source,java] 66 | ---- 67 | public class LambdaApp { 68 | 69 | public static void main(String[] args) { 70 | 71 | LambdaApp app = new LambdaApp(); 72 | 73 | // Örnek 2 (1) gibi 74 | app.fonk(2, 3, new Anonim() { // <1> 75 | @Override 76 | public int call(int a, int b) { 77 | return a + b; 78 | } 79 | }); 80 | 81 | } 82 | 83 | // Örnek 2 (2) gibi 84 | public int fonk(int a, int b, Anonim anonim) { 85 | return anonim.call(a, b) * 2; // <2> 86 | }; 87 | 88 | 89 | } 90 | ---- 91 | <1> Anonim iş birimi burada tanımlanıyor 92 | <2> Anonim iş birimi burada koşturuluyor 93 | 94 | === Java 8 ve Lambda ifadeleri 95 | 96 | LambdaApp sınıfının (1) numaralı kısmındaki anonim iş birimi, Javascript dilindeki karşılığına göre şu anda çok daha kompleks. 6 komut satırı yer işgal ediyor. Fakat bu fonksiyonun yaptığı tek iş var, 2 argüman almak ve toplayıp geri döndürmek. Bu anonim birimi sanıyorum şu biçimde temsil edebiliriz. 97 | 98 | [source,java] 99 | ---- 100 | fn(a,b) -> (a+b); 101 | ---- 102 | 103 | Görüldüğü üzere tek bir satırda aynı işi gören anonim iş birimini yani lambda ifadesini yazdık. Aynı örneği şimdi Java 8 Lambda deyimi ile yazalım. 104 | 105 | [source,java] 106 | ---- 107 | public interface Anonim{ 108 | public int call(int a, int b); 109 | } 110 | 111 | public class LambdaAppJava8 { 112 | 113 | public int fonk(int a, int b, Anonim anonim) { 114 | return anonim.call(a, b) * 2; 115 | }; 116 | 117 | public static void main(String[] args) { 118 | 119 | LambdaAppJava8 app = new LambdaAppJava8(); 120 | 121 | app.fonk(2, 3, (a, b) -> a + b); // Dikkat (1) 122 | } 123 | 124 | } 125 | ---- 126 | 127 | Görüldüğü üzere 6 satırlık anonim sınıf kullanımını, tek satıra düşürmüş olduk. 128 | 129 | Lambda ifadeleri, Java 8 versiyonunun en çarpıcı yeniliklerinden biri. (Bkz. http://openjdk.java.net/projects/lambda/[Project Lambda]). 130 | 131 | Sizler de Java 8 kullanmak istiyorsanız https://jdk8.java.net/ adresinden sisteminize kurabilirsiniz. 132 | 133 | Bol Javalı günler dilerim. -------------------------------------------------------------------------------- /chapter-05.asc: -------------------------------------------------------------------------------- 1 | == Lambda örnekleri 2 | 3 | `java.util.function` paketi altında bir çok fonksiyonel arayüz bulunmaktadır. Bu arayüzlerin temel amacı, farklı tipteki Lambda ifadelerine temel oluşturmaktır. 4 | 5 | === Consumer Arayüzü 6 | 7 | [source,java] 8 | ---- 9 | @FunctionalInterface 10 | public interface Consumer { 11 | 12 | void accept(T t); // t-> {} 13 | 14 | } 15 | ---- 16 | 17 | T tipindeki parametreyi alır ve tüketir/işler. Geriye değer döndürmez (void). T burada herhangi bir sınıf tipi olabilir. 18 | 19 | .Consumer Arayüzü Örnek 20 | [source,java] 21 | ---- 22 | Consumer consumer = word -> { 23 | System.out.println(word); // Merhaba Dünya 24 | }; 25 | 26 | consumer.accept("Merhaba Dünya"); 27 | ---- 28 | 29 | ''' 30 | 31 | === BiConsumer Arayüzü 32 | 33 | [source,java] 34 | ---- 35 | @FunctionalInterface 36 | public interface BiConsumer { 37 | 38 | void accept(T t, U u); // (t,u) -> {} 39 | } 40 | ---- 41 | 42 | T ve U tiplerinde iki parametre alır ve bu parametreleri tüketir. Geriye değer döndürmez. 43 | 44 | .BiConsumer Arayüzü Örnek 45 | [source,java] 46 | ---- 47 | BiConsumer biConsumer = (name, age) -> { 48 | System.out.println(name+":"+age); // Alinin yaşı:25 49 | }; 50 | biConsumer.accept("Ali'nin yaşı",25); 51 | ---- 52 | 53 | ''' 54 | 55 | === Function Arayüzü 56 | 57 | [source,java] 58 | ---- 59 | @FunctionalInterface 60 | public interface Function { 61 | 62 | R apply(T t); // t-> r 63 | 64 | } 65 | ---- 66 | 67 | T tipinde bir parametre alır, işler ve R tipinde bir değer döndürür. 68 | 69 | .Function Arayüzü Örnek 70 | [source,java] 71 | ---- 72 | Function function = t -> Math.pow(t,2); 73 | Integer result = function.apply(5); 74 | System.out.println(result); // 25 75 | ---- 76 | 77 | ''' 78 | 79 | === UnaryOperator Arayüzü 80 | 81 | [source,java] 82 | ---- 83 | @FunctionalInterface 84 | public interface UnaryOperator extends Function { 85 | 86 | } 87 | ---- 88 | 89 | Function türündendir. Eğer T ve R tipleri aynı türden ise, ismi UnaryOperator olur. 90 | 91 | .UnaryOperator Arayüzü Örnek 92 | [source,java] 93 | ---- 94 | UnaryOperator unaryOperator = a -> Math.pow(a,5); 95 | Integer result = unaryOperator.apply(2); 96 | System.out.println(result); // 32 97 | ---- 98 | 99 | ''' 100 | 101 | === BiFunction Arayüzü 102 | 103 | [source,java] 104 | ---- 105 | @FunctionalInterface 106 | public interface BiFunction { 107 | 108 | R apply(T t, U u); // (t,u) -> r 109 | } 110 | ---- 111 | 112 | T ve U tiplerinde iki parametre alır, R tipinde değer döndürür. T, U ve R herhangi bir sınıf tipi olabilir. Function#apply tek parametre alırken Bi* iki parametre alır. 113 | 114 | .BiFunction Arayüzü Örnek 115 | [source,java] 116 | ---- 117 | BiFunction biFunction = (a, b) -> "Sonuç:" + (a + b); 118 | String result = biFunction.apply(3,5); 119 | System.out.println(result); // Sonuç: 8 120 | ---- 121 | 122 | ''' 123 | 124 | === BinaryOperator Arayüzü 125 | 126 | [source,java] 127 | ---- 128 | @FunctionalInterface 129 | public interface BinaryOperator extends BiFunction { 130 | 131 | } 132 | ---- 133 | 134 | BiFunction türündendir. T, U ve R aynı tipte ise BinaryOperator kullanılabilir. 135 | 136 | .BinaryOperator Arayüzü Örnek 137 | [source,java] 138 | ---- 139 | BinaryOperator binaryOperator = (a, b) -> a + b; 140 | Integer result = binaryOperator.apply(3,5); 141 | System.out.println(result); // 8 142 | ---- 143 | 144 | ''' 145 | 146 | === Predicate Arayüzü 147 | 148 | [source,java] 149 | ---- 150 | @FunctionalInterface 151 | public interface Predicate { 152 | 153 | boolean test(T t); // t-> true/false 154 | } 155 | ---- 156 | 157 | T tipimde bir parametre alır, şarta bağlı olarak true/false değer döndürür. 158 | 159 | .Predicate Arayüzü Örnek 160 | [source,java] 161 | ---- 162 | Predicate predicate = a -> (a > 0); 163 | 164 | boolean pos = predicate.test(5); // true 165 | boolean neg = predicate.test(-5); // false 166 | ---- 167 | 168 | ''' 169 | 170 | === BiPredicate Arayüzü 171 | 172 | [source,java] 173 | ---- 174 | @FunctionalInterface 175 | public interface BiPredicate { 176 | 177 | boolean test(T t, U u); // (t,u) -> true/false 178 | } 179 | ---- 180 | 181 | T ve U tiplerinde iki parametre alır, şarta bağlı olarak true/false döndürür. 182 | 183 | .BiPredicate Arayüzü Örnek 184 | [source,java] 185 | ---- 186 | BiPredicate biPredicate = (a, b) -> (a > b); 187 | 188 | boolean bigger = biPredicate.test(5,4); // true 189 | boolean lower = biPredicate.test(5,7); // false 190 | ---- 191 | 192 | ''' 193 | 194 | === Supplier Arayüzü 195 | 196 | [source,java] 197 | ---- 198 | @FunctionalInterface 199 | public interface Supplier { 200 | 201 | T get(); // () -> t 202 | } 203 | ---- 204 | 205 | Hiç parametre almaz, T tipinde bir değer döndürür. Factory pattern için uygundur. 206 | 207 | .Supplier Arayüzü Örnek 208 | [source,java] 209 | ---- 210 | Supplier supplier = () -> new ArrayList<>(); 211 | List liste = supplier.get(); 212 | liste.add("Ali"); 213 | liste.add("Veli"); 214 | liste.add("Selami"); 215 | ---- 216 | 217 | Tekrar görüşmek dileğiyle... -------------------------------------------------------------------------------- /chapter-12.asc: -------------------------------------------------------------------------------- 1 | == Java 8 Embedded 2 | 3 | Java 8 Embedded, Java çalışma ortamını (JRE), sınırlı bellek imkanlarına sahip gömülü cihazlarda, az bellek tüketimli olarak sunmayı amaçlayan düşüncenin ürünüdür. 4 | 5 | Java çalışma ortamı, farklı işlemci ailesi ve farklı işletim sistemi ailelerine göre ayrıca hazırlandığı için platform bağımsızlığını sunmaktadır. Örneğin bugün `x86` mimarili bir işlemci için `Windows`, `Mac` ve `Linux` türevi işletim sistemlerinde hem çalışma ortamını hem geliştirme ortamını kullanabiliyoruz. Ha keza, `ARM 6/7` işlemci ailesine sahip makinelerde Java çalışma (JRE) ve geliştirme ortamını (JDK) kullanabiliyoruz. 6 | 7 | Gömülü sistemlerde `ARM` mimarili işlemciler çok fazla tercih ediliyor. Örneğin elinizdeki akıllı telefonun `ARM` ailesinden bir işlemci olma olasılığı çok çok yüksek. Popülerliği oldukça yüksek olan bir gömülü cihaz Raspberry PI' de `ARM` ailesinden bir işlemci kullanıyor. 8 | 9 | .Raspberry PI 10 | image::images/raspberry-pi.png[] 11 | 12 | Gömülü cihazların kendine has sınırlılıkları bulunuyor. Bu sınırlılıkların en başında ise bellek sınırlılığı geliyor. ARM işlemci ailesine göre yapılandırılmış full bir JRE, disk ortamında yaklaşık olarak 47 mb yer tutuyor. 47 MB göze çok gözükmeyebilir, ama, örneğin 64 MB bir belleğe sahip gömülü cihaz için 47 MB çok fazla! İşte tam da bu noktada Java 8 Embedded devreye giriyor. 13 | 14 | Java 8 Embedded, Java çalışma ortamını (JRE), gömülü cihazlar için kısmi modülerlik ile boyut olarak düşürmeyi amaçlamaktadır. Bu amaçla Java 8 Embedded geliştirim ihtiyaçlarına göre *3* tip JRE profili sunmaktadır. Bir de full profili katarsak toplamda 4 profil var. 15 | 16 | Java 8 Embedded, `compact 1`, `compact 2` ve `compact 3` profillerini sunmaktadır. Bu profillerde, en çok ihtiyaç duyulabilecek spesifik Java paketleri gruplandırılarak boyut bakımından küçülme sağlanmaktadır. 17 | 18 | Buna ilaveten, standart bir JRE için iki JVM modu bulunmaktadır. Bunlar `client` ve `server` mode dur. Bu iki seçenekte çalışma ortamına göre JIT Compiler bazında ayrıştırma yapılmaktadır. Java 8 Embedded için ise varsayılan olarak `client` ve `server` modu haricinde `minimal` modu gelmektedir. `minimal` modda bellek tüketimi minimize edilmektedir. Fakat bu modda azami `%5` 'lik bir performans düşümü makul karşılanmaktadır. 19 | 20 | Birbirini içerir biçimde yapılandırılan `Compact` profiller, sık tercih edileceği düşünülen paketler bazında gruplandırılmıştır. Bu gruplamayı aşağıdaki şekilden görebilmekteyiz. 21 | 22 | .`Full JRE` > `compact 3` > `compact 2` > `compact 1` 23 | image::images/compact-profiles.png[] 24 | 25 | Örneğin gömülü sisteminizde en temel Java paketlerini kullanacaksanız `compact 1` profilini seçmek size avantaj sağlayacaktır. `compact 1` profilinde hazırlanan JRE yaklaşık 9.5 MB'dir. Profiller arası boyutsal kıyaslamaya dair grafiği aşağıda görüyoruz. 26 | 27 | .Compact profile karşılaştırmaları 28 | image::images/compact-vss.png[] 29 | 30 | ==== JavaFX Extension 31 | 32 | JavaFX eklentisi kullanıldığında, gömülü cihazınızda JavaFX kullanmak için gerekli paketler Embedded JRE içine dahil edilmektedir. Elbette, oluşan çıktıların boyutları artmaktadır (Yaklaşık 10M kadar daha). 33 | 34 | [source,bash] 35 | ---- 36 | > jrecreate -p compact1 -x fx:controls --dest ejdk-compact1-javafx <1> 37 | > jrecreate -p compact2 -x fx:controls --dest ejdk-compact2-javafx <2> 38 | > jrecreate -p compact3 -x fx:controls --dest ejdk-compact3-javafx <3> 39 | ---- 40 | <1> `ejdk-compact1-javafx` dizininde `compact1` profilli `JavaFX` içeren JRE oluşturur. 41 | <2> `ejdk-compact2-javafx` dizininde `compact2` profilli `JavaFX` içeren JRE oluşturur. 42 | <3> `ejdk-compact3-javafx` dizininde `compact3` profilli `JavaFX` içeren JRE oluşturur. 43 | 44 | .Compact profile karşılaştırmaları (JavaFX dahil) 45 | image::images/compact-profiles-fx.png[] 46 | 47 | ==== Nashorn Extension 48 | 49 | Java 8 ile birlikte gelen Nashorn JavaScript motoru, bir eklenti olarak ürettiğiniz `ejre` içine dahil edilebilmektedir. Bu sayee JVM içinde JavaScript dilinde yazılan uygulamaları çalıştırma imkanı elde edilmektedir. Nashorn eklentisi `ejre` çıktısına yaklaşık `*1MB*` ilave etmektedir. 50 | 51 | [source,bash] 52 | ---- 53 | > jrecreate -p compact1 -x nashorn --dest ejdk-compact1-nashorn <1> 54 | > jrecreate -p compact2 -x nashorn --dest ejdk-compact2-nashorn <2> 55 | > jrecreate -p compact3 -x nashorn --dest ejdk-compact3-nashorn <3> 56 | ---- 57 | <1> `ejdk-compact1-nashorn` dizininde `compact1` profilli `Nashorn` içeren JRE oluşturur. 58 | <2> `ejdk-compact2-nashorn` dizininde `compact2` profilli `Nashorn` içeren JRE oluşturur. 59 | <3> `ejdk-compact3-nashorn` dizininde `compact3` profilli `Nashorn` içeren JRE oluşturur. 60 | 61 | NOTE: `-x` parametresiyle JavaFX eklentisi belirtildiğinde, JavaFX üretilen JRE içine dahil edilmektedir. `-x` parametresi `fx:controls`, `sunec`, `sunpkcs11`, `locales`, `charsets`, `nashorn` değerlerini kabul etmektedir. Birden fazlasını aynı anda kullanmak için (`,`) kullanılabilmektedir. 62 | 63 | === Java 8 ME vs Java 8 Embedded 64 | 65 | Java Me ile Java Embedded'in birbirine karıştırılması oldukça olası. Java ME, gömülü cihazlarda Java sanal makinesinin (JVM) çok çok küçük bellek tüketerek çalışmasına olanak sağlayan özel bir Java çalışma ortamıdır. Java 8 Me ile gömülü cihazların donanımsal birimlerini kontrol etmek mümkündür. Örneğin bir gömülü cihazın giriş/çıkış pinlerini, Watchdog Timer gibi bileşenlerini kullanabilirsiniz. Java ME içinde bunları kullanabilmek için özel paket ve sınıflar yer almaktadır. 66 | 67 | Tekrar görüşmek dileğiyle. -------------------------------------------------------------------------------- /chapter-10.asc: -------------------------------------------------------------------------------- 1 | == Java 8 ve JVM Dilleri 2 | 3 | Java Sanal Makinesi (JVM), Java 7 ile başlayan http://openjdk.java.net/projects/mlvm/[Da Vinci Machine] projesiyle, özellikle dinamik tipli dilleri JVM üzerinde çalışabilir kılmaktadır. 4 | 5 | Sun Microsystem'in ilk adımlarını attığı bu proje, Oracle firmasıyla beraber de önem verilen bir konu olmaya devam etmektedir. JVM içerisinde statik tipli dilleri çalıştırabilmenin birden fazla amacı bulunmaktadır. Bunlar; 6 | 7 | * JIT (Just in Time) Compiler ile yüksek performans sunmak 8 | * Birçok dilin çalıştırılmasıyla JVM'i http://en.wikipedia.org/wiki/Polyglot_(computing)[Polyglot] bir ortam haline getirmek 9 | * Farklı dil ve ekosistemleri Java ekosistemine yakınlaştırmak 10 | * Farklı dil ekosistemlerinin gücünü JVM'de birleştirmek 11 | 12 | === JVM Dilleri 13 | 14 | Halihazırda Java Sanal Makinesi üzerinde birçok programlama dili çalıştırılabilmektedir. Bu diller <>nda olduğu gibidir; 15 | 16 | .JVM Dilleri Tablosu 17 | [[jvm-dilleri-tablosu]] 18 | [width="100%",options="header",cols="1,2"] 19 | |==================== 20 | |Dil |Uygulayıcı kütüphane 21 | |Ada |JGNAT 22 | |BBx |BBj is a superset of BBx, PRO/5, and Visual PRO/5. 23 | |C |C to Java Virtual Machine compilers 24 | 1.3+|CFML |Adobe ColdFusion |Railo |Open BlueDragon 25 | 1.2+|Common Lisp |Armed Bear Common Lisp |CLforJava 26 | 1.2+|JavaScript |Rhino |Nashorn 27 | 1.2+|Pascal |Free Pascal |MIDletPascal 28 | |Perl 6 |Rakudo Perl 6 29 | 1.2+|Prolog |JIProlog |TuProlog 30 | |Python |Jython 31 | |REXX |NetRexx 32 | |Ruby |JRuby 33 | 1.4+|Scheme |Bigloo |Kawa |SISC |JScheme 34 | |Tcl |Jacl 35 | |==================== 36 | *Kaynak*: http://en.wikipedia.org/wiki/List_of_JVM_languages[List of JVM languages] 37 | 38 | <>nda listelenen programlama dilleri JVM bünyesinde koşturulabilmektedir. Bazı diller yorumlama usülüyle koşturulurken, bazıları ise bayt koda dönüştürüldükten sonra koşturulmaktadır. Fakat, JavaScript haricindeki dillere karşılık bir uygulayıcı kütüphaneyi projenize eklemeniz gerekmektedir. 39 | 40 | Örneğin JVM üzerinde Ruby dili ile uygulama geliştirmek istiyoranız, JRuby bağımlılığını Java projenize eklemelisiniz. 41 | 42 | .JRuby Maven Dependency 43 | [source,java] 44 | ---- 45 | 46 | org.jruby 47 | jruby 48 | 1.7.16 49 | 50 | ---- 51 | 52 | Diğer listeli diller için de benzer biçimde gereken bağımlılık Java projenize eklenmelidir. 53 | 54 | Fakat, JavaScript programlama dili için olay biraz farklı bir durumda. Çünkü, Java 7 Rhino, Java 8 ise Nashorn isimli JavaScript motorlarını gömülü olarak JVM içerisinde bulundurmaktadır. Bu Java ekosisteminin JavaScript diline ne kadar önem verdiğini ayrıca göstermektedir. 55 | 56 | === Java Scripting API 57 | 58 | Java programlama dili, tüm bu listeli dilleri koşturabilmek için ortak arayüzlerin bulunduğu bir API sunmaktadır. Java Scripting API bileşenleri `http://docs.oracle.com/javase/8/docs/api/javax/script/package-summary.html[javax.script]` paketi içerisinde bulunmaktadır. 59 | 60 | `javax.script` paketi oldukça basit arayüz ve sınıflar içermektedir.Bunlardan en önemlisi `ScriptEngine` arayüzüdür. 61 | 62 | === ScriptEngine 63 | 64 | ScriptEngine türünden nesneler, `ScriptEngineManager#getEngineByName` metodu üzerinden eşsiz bir takma isim ile elde edilmektedir. Bu nesneler ile, String türünden kod blokları koşturulabilmekte, ayrıca Java ile iletişim kurulabilmektedir. Örneğin, Nashorn JavaScript motoru için `"nashorn"` veya `"rhino"` takma adları, Ruby için ise `"jruby"` takma adı kullanılmaktadır. 65 | 66 | Örneğin; 67 | 68 | [source,java] 69 | ---- 70 | ... 71 | ScriptEngineManager engineManager = new ScriptEngineManager(); 72 | 73 | ScriptEngine engine = engineManager.getEngineByName("nashorn"); <1> 74 | ScriptEngine engine = engineManager.getEngineByName("rhino"); <2> 75 | ScriptEngine engine = engineManager.getEngineByName("jruby"); <3> 76 | ScriptEngine engine = engineManager.getEngineByName("jython"); <4> 77 | ... 78 | ---- 79 | <1> Java 8 için JavaScript motoru 80 | <2> Java 7 için JavaScript motoru 81 | <3> Ruby için JRuby motoru 82 | <4> Python için Jython motoru 83 | 84 | === Nashorn JavaScript Motoru 85 | 86 | Nashorn, Java 8 için özel olarak sıfırdan geliştirilen bir JavaScript motorudur. Nashorn, Rhino JavaScript motoruna göre 5 kat daha fazla performans sunmaktadır. 87 | 88 | Nashorn JavaScript motoru `EcmaScript 5` standardını desteklemekte ve tüm testlerini başarıyla geçmiş bulunmaktadır. 89 | 90 | JVM dillerinden Java Scripting API destekleyenler, `ScriptEngine#eval` metodu ile kod bloklarını koşturma imkanı elde etmektedir. Bu sayede ortak arayüz bileşenleri üzerinden Java harici diller JVM üzerinde koşturulabilmektedir. 91 | 92 | .Nashorn Engine Örneği 93 | [source,java] 94 | ---- 95 | ScriptEngineManager engineManager = new ScriptEngineManager(); 96 | 97 | ScriptEngine engine = engineManager.getEngineByName("nashorn"); <1> 98 | 99 | engine.eval("function topla(a,b){ return a + b; }"); <2> 100 | String sonuc=(String)engine.eval("topla(3,5);"); <3> 101 | System.out.println(sonuc); // 8 102 | ---- 103 | <1> Nashorn Engine elde ediliyor. 104 | <2> `topla` isimli JavaScript fonksiyonu tanımlanıyor. 105 | <3> `topla` fonksiyonu Nashorn ile koşturuluyor, ve sonucu elde ediliyor. 106 | 107 | Siz de Java Scripting API destekleyen diğer dilleri JVM ekosisteminde koşturabilirsiniz. 108 | 109 | [NOTE] 110 | ==== 111 | Nashorn JS engine JDK 11'de devre dışı bırakıldı. Detaylar: https://openjdk.java.net/jeps/335 112 | ==== 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /chapter-11.asc: -------------------------------------------------------------------------------- 1 | == Java 8 Optional Yeniliği 2 | 3 | Bir Java geliştiricisinin korkulu rüyası `NullPointerException` istisnalarıyla uğraşmaktır. `null` değer ile karşılaşmak, ona karşı önlem almak herzaman için can sıkıcı olmuştur. Bu can sıkıcılığı ortadan kaldırmak için Java 8 içerisinde `Optional` sınıfı getirilmiştir. `Optional` yapısı daha evvelden farklı dil ortamlarında bulunan bir özelliktir. 4 | 5 | `Optional` türünden nesneler, `null` olma ihtimali olan alanları kolay yönetmek için oluşturulmuştur. 6 | 7 | === Optional Oluşturmak 8 | 9 | Bir `Optional` nesnesi, `Optional` sınıfının çeşitli statik metodlarıyla oluşturulmaktadır. Bunlar `empty`, `of` ve `ofNullable` 'dir. 10 | 11 | empty:: Taze bir `Optional` nesnesi oluşturur. 12 | of:: Bir nesneyi `Optinal` ile sarmalar. Parametre olarak `null` değer kabul etmez. 13 | ofNullable:: Bir nesneyi `Optinal` ile sarmalar. Parametre olarak `null` değer kabul eder. 14 | 15 | *Örneğin* 16 | 17 | [source,java] 18 | ---- 19 | Optional empty = Optional.empty(); <1> 20 | Optional of = Optional.of("Merhaba Dünya"); <2> 21 | Optional ofNull = Optional.of(null); <3> 22 | Optional ofNullable = Optional.ofNullable(null); <4> 23 | ---- 24 | <1> Değer içermeyen Opt 25 | <2> String türünden değer içeren Opt 26 | <3> `Optional#of` `null` kabul etmez. İstisna fırlatır. 27 | <4> `Optional#ofNullable` `null` kabul eder. İstisna fırlatmaz. 28 | 29 | === #ifPresent - Varsa yap, yoksa yapma 30 | 31 | Eğer bir `Optional` içerisinde sadece veri varsa (`null` değilse) bir işin yapılması isteniyorsa `#ifPresent` metodu kullanılabilir. `#ifPresent` metodu `Consumer` fonksiyonel arayüzü türünden bir nesne kabul etmektedir. 32 | 33 | Örneğin bir sayının karesini almaya çalışalım. Kullanılan değişken `null` değerini referans ediyorsa `NullPointerException` istisnası alınacaktır. 34 | 35 | [source,java] 36 | ---- 37 | Integer numara = null; 38 | 39 | Double karesi = Math.pow(numara , 2); <1> 40 | 41 | System.out.println("Sonuç: " + karesi); 42 | ---- 43 | <1> Exception in thread "main" `java.lang.NullPointerException` 44 | 45 | Bu istisna için `if` deyimiyle karşı önlem alınabilir. 46 | 47 | [source,java] 48 | ---- 49 | Integer numara = null; 50 | 51 | if(numara != null) { 52 | 53 | Double karesi = Math.pow(numara , 2); 54 | 55 | System.out.println("Sonuç: " + karesi); 56 | 57 | } 58 | ---- 59 | 60 | Fakat `if` deyimiyle birlikte `!` , `==` , `!=` ifadelerini kullanmak akıcı bir geliştirim deneyimi sunmaz. Ayrıca bu durum hata yapılmasına daha açıktır. Bunun yerine `Optional#ifPresent` metodunu kullanabiliriz. 61 | 62 | [source,java] 63 | ---- 64 | Integer numara = null; 65 | 66 | Optional opt = Optional.ofNullable(numara); 67 | 68 | opt.ifPresent(num -> { 69 | Double karesi = Math.pow(num , 2); 70 | System.out.println("Sonuç: " + karesi); 71 | }); 72 | ---- 73 | 74 | === #map - Dönüştürme 75 | 76 | `Optional` nesnelerinin sarmaladığı veriler üzerinde dönüştürüm yapılabilmektedir. Bir önceki örneği bu şekilde yeniden yazabiliriz. 77 | 78 | [source,java] 79 | ---- 80 | Integer numara = null; 81 | 82 | Optional opt = Optional.ofNullable(numara); 83 | 84 | opt 85 | .map(num->Math.pow(num,2)) 86 | .ifPresent(System.out::println); 87 | ---- 88 | 89 | === #filter - Filtreleme 90 | 91 | `Optional` nesnelerinin sarmaladığı veriler üzerinde süzme işlemi de yapılabilmektedir. 92 | 93 | Örneğin aşağıdaki kod parçası yerine; 94 | 95 | [source,java] 96 | ---- 97 | String message = null; 98 | 99 | if (message != null) 100 | if (message.length() > 5) 101 | System.out.println(message); 102 | ---- 103 | 104 | Aşağıdaki `Optional` karşılığını kullanabiliriz. 105 | 106 | [source,java] 107 | ---- 108 | String message = null; 109 | Optional opt = Optional.ofNullable(message); 110 | 111 | opt 112 | .filter(m -> m.length() > 5) 113 | .ifPresent(System.out::println); 114 | ---- 115 | 116 | === #orElse - Varsa al, yoksa bunu al 117 | 118 | `orElse` metodu daha çok ternary (`üçlü`) şart ihtiyacı olduğu durumlarda ihtiyaç duyulabilir. Daha akıcı bir geliştirim deneyimi sunar. 119 | 120 | .numara `null` değilse numarayı döndür, `null` ise `0` döndür. 121 | 122 | [source,java] 123 | ---- 124 | 125 | Integer numara = null; 126 | 127 | int result = (numara != null) ? numara : 0; 128 | ---- 129 | 130 | Yukarıdaki üçlü şartı `orElse` ile birlikte kullanabiliriz. 131 | 132 | [source,java] 133 | ---- 134 | Integer numara = null; 135 | 136 | Optional opt = Optional.ofNullable(numara); 137 | 138 | int result = opt.orElse(0); 139 | ---- 140 | 141 | === #orElseGet - Varsa al, yoksa üret 142 | 143 | Bu metod `orElse` metoduna çok benzer, fakat `orElseGet` metod parametresi olarak `Supplier` fonksiyonel arayüzü türünden nesne kabul eder. 144 | 145 | [source,java] 146 | ---- 147 | List names = Arrays.asList("Ali","Veli","Selami"); 148 | 149 | Optional> opt = Optional.ofNullable(names); 150 | 151 | names = opt.orElseGet(()-> new ArrayList()); <1> 152 | 153 | names = opt.orElseGet(ArrayList::new); <2> 154 | ---- 155 | <1> Lambda ile 156 | <2> Metod referans ile 157 | 158 | === #orElseThrow - Varsa al, yoksa fırlat 159 | 160 | `Optional` nesnesi bir değeri içeriyorsa (`null` olmayan) o değeri döndürür, `null` ise de sağlanan istisna nesnesini fırlatır. `orElseThrow` metodu `Supplier` türünden bir nesne kabul eder. 161 | 162 | [source,java] 163 | ---- 164 | Integer numara = null; 165 | 166 | Optional opt = Optional.ofNullable(numara); 167 | 168 | int result = opt.orElseThrow(RuntimeException::new); <1> 169 | ---- 170 | <1> Varsa döndürür, yoksa yeni bir `RuntimeException` istisnası fırlatır. 171 | 172 | Java 8 yeniliklerini http://kodcu.com/java-8-ebook/[Java 8 Ebook] ile öğrenebilirsiniz. 173 | 174 | Tekrar görüşmek dileğiyle. -------------------------------------------------------------------------------- /chapter-04.asc: -------------------------------------------------------------------------------- 1 | == Consumer Arayüzü 2 | 3 | Daha önceki yazılarımızda Lambda ifadelerinden ve Fonskiyonel arayüzlerden bahsetmiştik. Şimdi ise, `java.util.function` paketi altında yer alan ve gömülü olarak bulunan fonksiyonel arayüzlere değineceğiz. 4 | 5 | java.util.function paketi altında, farklı amaçlar için bulunan hazır arayüzler bulunmaktadır. Java 8 içerisinde Lambda deyimlerinin kullanılabilir kılınmasında, java.util.function paketi altındaki arayüzler kullanılmaktadır. Bu fonksiyonel arayüzlere http://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html[java.util.function] adresinden görebilirsiniz. 6 | 7 | Bu yazımızda ise, fonksiyonel arayüzlere giriş düşüncesiyle `java.util.function.Consumer` arayüzünden ve nasıl kullanıldığından bahsedeceğiz. `Consumer` arayüzü accept isimli tek bir metoda sahiptir. Bu fonksiyonun bulunuş amacı, tüketim operasyonlarında kullanılmasıdır. Tüketimden kasıt edilen ise, metoda girdi olması fakat çıktı olmamasıdır. Metod girdisinin tipi ise jenerik olarak `T` harfi ile temsil edilmiştir. `T` yerine, isteğe göre herhangi bir Java tipi gelebilir. Biz String tipini kullanacağız. 8 | 9 | [source,java] 10 | ---- 11 | @FunctionalInterface 12 | public interface Consumer { 13 | 14 | void accept(T t); 15 | 16 | } 17 | ---- 18 | 19 | Consumer arayüzü, yukarıda görüldüğü üzere bir fonksiyonel arayüzdür. Bir arayüzün, fonksiyonel olarak nitelenebilmesi için, tek bir soyut metoda sahip olma şartı vardır. Zaten bu sayede, fonksiyonel arayüzler Lambda deyimlerine öykünebilmektedirler. 20 | 21 | === Java 8 öncesi 22 | 23 | Java 8 öncesine göre Consumer arayüzü türünden bir nesneyi anonim bir sınıf ile oluşturulım. 24 | 25 | [source,java] 26 | ---- 27 | Consumer consumer = new Consumer() { 28 | @Override 29 | public void accept(String msg) { 30 | System.out.println(msg); 31 | } 32 | }; 33 | 34 | consumer.accept("Merhaba Dünya"); 35 | ---- 36 | 37 | Görüldüğü üzere bir anonim sınıf oluşturduk ve accept metodunu tükettik. 38 | 39 | === Java 8 sonrası 40 | 41 | Java 8 sonrası için anonim fonksiyonlar yerine Lambda deyimlerini kullanabilmekteyiz. Örneğin yukarıdaki anonim sınıfı aşağıdaki yer alan Lambda deyimi ile yer değiştirebiliriz. 42 | 43 | [source,java] 44 | ---- 45 | Consumer consumer = (String msg) -> { 46 | System.out.println(msg); 47 | }; 48 | 49 | consumer.accept("Merhaba Dünya"); 50 | ---- 51 | 52 | Lambda deyimlerinde odaklanması gereken nokta, fonksiyonel arayüzün tek metodunun sahip olduğu metod girdi tipi, sayısı,sırası ve metod çıktı tipidir. Bu sayede kod satırı olarak tasaruf edilmektedir. 53 | 54 | === Lambda deyimleri akıllıdır 55 | 56 | Lambda fonksiyonlarında tanımlanan metod girdi tanımlamalarında, istenirse tip tanımlamasından feragat edilebilir. Yani yukarıdaki Lambda deyimini aşağıdaki gibi yazabiliriz. 57 | 58 | [source,java] 59 | ---- 60 | Consumer consumer = (msg) -> { 61 | System.out.println(msg); 62 | }; 63 | 64 | consumer.accept("Merhaba Dünya"); 65 | ---- 66 | 67 | Görüldüğü gibi, (String msg) tanımlamasını (msg) yapabildik. Sol tarafta zaten String tip bilgisi yer aldığından, compiler metod girdisinin tipini buradan elde edecektir. Tip tanımlamalarından feragat ettiğimiz gibi parantezden de kurtulabiliriz. 68 | 69 | [source,java] 70 | ---- 71 | Consumer consumer = e -> { 72 | System.out.println(e); 73 | }; 74 | 75 | consumer.accept("Merhaba Uranüs"); 76 | ---- 77 | 78 | === Consumer arayüzü nerede kullanılıyor? 79 | 80 | JDK 8 in çekirdeğinde java.util.function arayüzleri halihazırda kullanılmaktadır. Örneğin Iterable arayüzünün içerisinde forEach metodunda Consumer arayüzü kullanılmaktadır. 81 | 82 | [source,java] 83 | ---- 84 | public interface Iterable { 85 | 86 | ... 87 | 88 | default void forEach(Consumer action) { 89 | Objects.requireNonNull(action); 90 | for (T t : this) { 91 | action.accept(t); 92 | } 93 | } 94 | 95 | ... 96 | } 97 | ---- 98 | 99 | forEach metodu, önce null kontrolü yapmakta ve ardından, döngüsel olarak mevcut veri tipi üzerinde veri tüketimi yapmaktadır. Şimdi bu metodu kullanan basit bir örnek yazalım. 100 | 101 | [source,java] 102 | ---- 103 | List names = Arrays.asList("Ali", "Veli", "Selami"); 104 | 105 | names.forEach(consumer); 106 | 107 | // veya 108 | 109 | names.forEach(e -> { 110 | System.out.println(e); 111 | }); 112 | ---- 113 | 114 | Bu örnek içerisinde her bir isim bilgisi tek tek konsol ekranına çıktılanmaktadır. 115 | 116 | === Lambda deyimlerini Metod Referansları ile kullanabiliriz. 117 | 118 | Java 8 evvelinde bir metodu referans olarak kullanma şansı bulunmuyordu. Fakat Java 8 ile birlikte Java metodlarını referans olarak kullanabiliyoruz. Örneğin, elimizde halihazırda aşağıdaki gibi bir listele metodu bulunsun. 119 | 120 | [source,java] 121 | ---- 122 | public class App{ 123 | 124 | public static void listele(String e) { 125 | System.out.println(e); 126 | } 127 | 128 | } 129 | ---- 130 | 131 | Dikkat edilirse bu metodun girdi ve çıktı normu, Consumer#accept metodunun girdi ve çıktı biçimiyle birebir aynıdır. Bu sebeple, listele metodu metod referansı olarak Consumer tipi için kullanılabilirdir. 132 | 133 | [source,java] 134 | ---- 135 | Consumer consumer= App::listele; 136 | 137 | consumer.accept("Merhaba Dünya"); 138 | ---- 139 | 140 | Bir metodu referans olarak kullanabilmek için :: ifadesi kullanılmaktadır. Şimdi metod referans kullanımını örnek olarak forEach metodu üzerinde deneyelim. 141 | 142 | [source,java] 143 | ---- 144 | List names = Arrays.asList("Ali", "Veli", "Selami"); 145 | 146 | names.forEach(App::listele); 147 | ---- 148 | 149 | `App#listele` metodunun bir benzerinin yazılmışı zaten PrintStream sınıfı içerisinde var. 150 | 151 | [source,java] 152 | ---- 153 | List names = Arrays.asList("Ali", "Veli", "Selami"); 154 | 155 | names.forEach(System.out::print); 156 | 157 | // veya 158 | 159 | names.forEach(System.out::println); 160 | ---- 161 | 162 | Şimdilik bu kadar, tekrar görüşmek dileğiyle. -------------------------------------------------------------------------------- /chapter-07.asc: -------------------------------------------------------------------------------- 1 | == Method Reference 2 | 3 | Java programlama dilinde metodlar, sınıfların içinde bulunan iş birimleridir. 4 | 5 | Metodlara erişimin ise statik olup olmadığına göre iki erişim biçimi vardır. Statik metodlara sınıf üzerinden erişilebilirken, statik olmayan metodlara nesne üzerinden erişim sağlanabilmektedir. 6 | 7 | Java 8 ile beraber metod birimleri, bir lambda ifadesine, dolayısıyla bir fonksiyonel arayüze karşılık olarak referans verilebilmektedir. 8 | 9 | Lambda ifadeleri yazılırken, tek metoda sahip arayüzün (fonksiyonel arayüz) metod girdi ve çıktısı baz alınmaktadır. Eğer daha önce yazdığınız bir metodun girdi ve çıktısı, bir fonksiyonel arayüz metodunun girdi ve çıktısına birebir uyuyorsa, o metod bir lambda deyimi yerine kullanılabilmektedir. 10 | 11 | *Örneğin;* 12 | 13 | Consumer arayüzü `T` türünde tek bir parametre alır. Metod dönüşü `void` 'dir. 14 | 15 | [source,java] 16 | ---- 17 | @FunctionalInterface 18 | public interface Consumer { 19 | 20 | void accept(T t); // t-> {} 21 | 22 | } 23 | ---- 24 | 25 | Yukarıdaki `Consumer` arayüzü türünden bir nesneyi, `e` -> `{}` lambda deyimiyle oluşturabiliriz. 26 | 27 | 28 | [source,java] 29 | ---- 30 | Consumer consumerWithLambda = e-> { 31 | 32 | }; 33 | ---- 34 | 35 | Lambda ifadeleri yazarken metod girdi ve çıktısına odaklandığımıza göre, lambda deyimiyle birebir örtüşen metodları, lambda deyimleri yerine kullanabilir miyiz? Bunu aşağıdaki metod üzerinden düşünelim. 36 | 37 | [source,java] 38 | ---- 39 | public void herhangiBirMetod(String e){ 40 | 41 | } 42 | ---- 43 | 44 | Yani `herhangiBirMetod` metodunun imzasıyla `Consumer` arayüzünün accept metodunun imzası birbiriyle aynıdır. `herhangiBirMetod`, String türünden tek bir parametre almaktadır, metod dönüşü ise `void` 'dir. Bu uyum neticesinde eğer istenirse, bu metodun referansı ile `Consumer` türünden bir nesne oluşturulabilir. 45 | 46 | === Bir metodu referans vermek 47 | 48 | Java programlama dilinde bir metodun nasıl referans verileceği metodun statik olup olmadığına göre değişmektedir. Bir metodun referans olarak verilebilmesi için ise `::` ikilisi kullanılır. 49 | 50 | .Statik metodlarda 51 | 52 | Statik metodlar sınıfa ait bileşenlerdir. Bu yüzden erişim kurulurken dahili olduğu sınıf üzerinden erişim kurulur. 53 | 54 | .Örneğin; 55 | [source,java] 56 | ---- 57 | Consumer consumerWithMetRef = ::herhangiBirMetod; 58 | ---- 59 | 60 | .Statik olmayan metodlarda 61 | 62 | Statik olmayan metodlar nesneye ait bileşenlerdir. Bu sebeple nesnenin referansı üzerinden erişilmelidirler. 63 | 64 | .Örneğin; 65 | [source,java] 66 | ---- 67 | Consumer consumerWithMetRef = ::herhangiBirMetod; 68 | ---- 69 | 70 | .Örnek 1 71 | 72 | Şimdi birkaç örnek ile metod referansları deneyimleyelim. Aşağıda `"Ali"`,`"Veli"`,`"Selami"` verilerini içeren bir List nesnesi bulunmaktadır. Bu nesnenin ise, `forEach` isimli metodu bulunmaktadır. Bu nesnenin kabul ettiği parametre ise `Consumer` türündendir. 73 | 74 | [source,java] 75 | ---- 76 | List names= Arrays.asList("Ali,Veli,Selami"); 77 | 78 | names.forEach(new Consumer() { <1> 79 | @Override 80 | public void accept(String s) { 81 | System.out.println(s); 82 | } 83 | }); 84 | ---- 85 | <1> Sırayla konsole çıktılar. 86 | 87 | Şimdi bu örneği `Lambda` ifadesiyle yeniden aşağıdaki gibi yazabiliriz. 88 | 89 | 90 | [source,java] 91 | ---- 92 | List names= Arrays.asList("Ali,Veli,Selami"); 93 | 94 | names.forEach(s->{ 95 | System.out.println(s); 96 | }); 97 | ---- 98 | 99 | Lambda ifadesi, satır sayısı bazında kodu iyice kısalttı. Şimdi bu aynı işi metod referans kullanarak yapalım. 100 | 101 | [source,java] 102 | ---- 103 | public class App{ 104 | 105 | static List names= Arrays.asList("Ali,Veli,Selami"); 106 | 107 | // Statik metod 108 | public static void herhangiBirMetod(String s){ 109 | System.out.println(s); 110 | } 111 | 112 | // Non-statik metod 113 | public void digerBirMetod(String s){ 114 | System.out.println(s); 115 | } 116 | 117 | 118 | public static void main(String[] args){ 119 | 120 | names.forEach(App::herhangiBirMetod); <1> 121 | 122 | // veya 123 | 124 | App app=new App(); 125 | names.forEach(app::digerBirMetod); <2> 126 | 127 | // veya 128 | 129 | names.forEach(System.out::println); <3> 130 | } 131 | 132 | } 133 | ---- 134 | <1> Statik metodu referans vermek 135 | <2> Non-statik metodu referans vermek 136 | <3> Diğer bir örnek 137 | 138 | .Örnek 2 139 | 140 | `Collections#sort` metodu ile bir dizi nesneyi sıralamak istiyoruz diyelim. Bu sıralamayı, metodun 2. parametresinde `Comparator` türünden bir nesne ile kontrol edebiliriz. 141 | 142 | [source,java] 143 | ---- 144 | List numbers = Arrays.asList(5, 10, 1, 5, 6); 145 | 146 | Collections.sort(numbers, new Comparator() { 147 | @Override 148 | public int compare(Integer o1, Integer o2) { 149 | return o1 - o2; 150 | } 151 | }); 152 | ---- 153 | 154 | NOTE: Fonksiyonel olarak `Comparator` arayüzü ve `java.util.BiFunction` arayüzü birebir aynıdır. 155 | 156 | Şimdi anonim olarak oluşturulan `Comparator` türünden nesneyi Lambda ifadeleriyle yeniden yazalım. 157 | 158 | 159 | [source,java] 160 | ---- 161 | List numbers = Arrays.asList(5, 10, 1, 5, 6); 162 | 163 | Collections.sort(numbers, (o1, o2) -> o1 - o2) 164 | ---- 165 | 166 | Şimdi ise Lambda deyimi yerine metod referans kullanarak bu işi yapalım. 167 | 168 | [source,java] 169 | ---- 170 | public Integer sirala(Integer o1, Integer o2){ 171 | 172 | return o1 - o2; 173 | 174 | } 175 | 176 | public void birMetod(){ 177 | 178 | List numbers = Arrays.asList(5, 10, 1, 5, 6); 179 | 180 | Collections.sort(numbers, this::sirala); <1> 181 | } 182 | ---- 183 | <1> Lambda yerine metod referansı 184 | 185 | Metod referans kullanmak var olan iş mantığını kolay bir biçimde referans vermeye olanak sağlamaktadır. 186 | 187 | Tekrar görüşmek dileğiyle. -------------------------------------------------------------------------------- /chapter-03.asc: -------------------------------------------------------------------------------- 1 | == Tarih ve Saat işlemleri 2 | 3 | Java 8 içerisinde zaman temsili için yeni bir Date-Time API geliştirildi. Java programlama dilinde zamansal işlemler için JSR 310: Date and Time API şartnamesi yer almaktadır. Java 8 ile birlikte yeniden düzenlenen bu şartname, yepyeni özellikler sunmaktadır. Yeni geliştirilen Date-Time API’nin referans implementörü ThreeTen projesidir. 4 | 5 | Yeni Date-Time API ile kolay kullanım, anlaşılırlık, thread-safety gibi hususlarda iyileştirmeler karşımıza çıkıyor. Bu yeni API’ ye dair bileşenler (sınıf, arayüz, enum vs.) java.time paketi altında yer almaktadır. Şimdi sizlerle java.time paketi içerisinde yer alan bileşenler ile ilgili kolay anlaşılır örnekler paylaşmak istiyorum. 6 | 7 | java.time paketindeki sınıfların genel olarak kurucu metodu private erişim belirleyicisine sahiptir, bu sebeple new anahtar ifadesiyle oluşturulamazlar. Onun yerine now, of , from, parse gibi metodlarla yeni nesneler oluşturulabilmektedir. java.time paketi içerisindeki zamansal sınıflar immutable’ dir. Bu sebeple bir nesne oluşturulduktan sonra içerisindeki veriler kesinlikle düzenlenemezler. Bu da mevcut sınıfları thread-safety hale getirmektedir. ( 8 | Bkz. Thread safety & immutability). Bu yazımızda `LocalDate`, `LocalTime`, `LocalDateTime`, `ZoneId` ve `ZonedDateTime` sınıflarının kullanımını irdeleyeceğiz. 9 | 10 | === LocalDate 11 | 12 | LocalDate sınıfı ile tarihsel zaman temsil edilir. Örneğin: `10/10/2010` tarihini `LocalDate` ile temsil edebiliriz. 13 | 14 | *Örnekler* 15 | 16 | *"of"* metodu ile `LocalDate` nesnesi oluşturulabilir. 17 | 18 | [source,java] 19 | ---- 20 | LocalDate.of(1988, 07, 16); // 1988-07-16 21 | LocalDate.of(1988, Month.JULY, 16) // 1988-07-16 (Month enum) 22 | ---- 23 | 24 | *"now"* metodu ile o anın tarihi elde edilir. 25 | 26 | [source,java] 27 | ---- 28 | LocalDate now = LocalDate.now(); // 2014-04-05 29 | ---- 30 | 31 | *"with***"* metodu ile eldeki bir `LocalDate` için gün, ay, yıl alanları düzenlenebilir. LocalDate sınıfı `immutable` ’dir. Bu sebeple with metodu farklı bir LocalDate nesne döndürür. O anki nesneyi düzenlemez. 32 | 33 | [source,java] 34 | ---- 35 | LocalDate now = LocalDate.now(); // 2014-04-05 36 | 37 | now.withYear(2016); // 2016-04-05 38 | 39 | now.withMonth(8).withDayOfMonth(17); // 2014-08-17 40 | 41 | now 42 | .with(ChronoField.YEAR, 2012) 43 | .with(ChronoField.MONTH_OF_YEAR, 8) 44 | .with(ChronoField.DAY_OF_MONTH,3); // 2012-08-03 45 | ---- 46 | 47 | *"plus***"* metodu ile eldeki bir LocalDate için gün, ay, yıl alanları artırılabilir. `LocalDate` sınıfı immutable’dir. Bu sebeple `plus` metodu farklı bir LocalDate nesne döndürür. O anki nesneyi düzenlemez. 48 | 49 | [source,java] 50 | ---- 51 | now 52 | .plusWeeks(2) 53 | .plusDays(3) 54 | .plusYears(3) 55 | .plusDays(7); // 56 | 57 | now 58 | .plus(2, ChronoUnit.WEEKS) 59 | .plus(3, ChronoUnit.YEARS) 60 | .plus(3, ChronoUnit.DECADES); // 61 | ---- 62 | 63 | *"minus***"* metodu ile eldeki bir LocalDate için `gün`, `ay`, `yıl` alanları azaltılabilir. `LocalDate` sınıfı immutable’dir. Bu sebeple minus metodu farklı bir LocalDate nesne döndürür. O anki nesneyi düzenlemez. 64 | 65 | [source,java] 66 | ---- 67 | now.minusDays(5).minusMonths(2); // 68 | 69 | now 70 | .minus(2, ChronoUnit.WEEKS) 71 | .minus(3, ChronoUnit.YEARS) 72 | .minus(33, ChronoUnit.DAYS); // 73 | ---- 74 | 75 | === LocalTime 76 | 77 | LocalTime sınıfı ile saatsel zaman temsil edilir. Örneğin: `20:11 , 18:15:55` saatlerini LocalTime ile temsil edebiliriz. `LocalTime` ile saat, dakika, saniye, salise temsil edilebilir. 78 | 79 | *Örnekler* 80 | 81 | [source,java] 82 | ---- 83 | LocalTime now= LocalTime.now(); 84 | 85 | LocalTime time= LocalTime.of(18, 20, 55); // 18:20:55 86 | 87 | time.getHour(); // 18 88 | time.getMinute(); // 20 89 | time.getSecond(); // 55 90 | 91 | LocalTime.NOON; // 12:00 92 | LocalTime.MIDNIGHT; // 00:00 93 | 94 | LocalTime.parse("10:05"); // 10:05 95 | 96 | time 97 | .plusSeconds(45) 98 | .minusSeconds(5) 99 | .minus(5, ChronoUnit.SECONDS); // 18:20:35 100 | ---- 101 | 102 | === LocalDateTime 103 | 104 | LocalDateTime sınıfı ile hem tarihsel hem saatsel zaman temsil edilir. Örneğin: `10/10/2010 15:22:33` zamanını `LocalDateTime` ile sınıfsal olarak temsil edebiliriz. 105 | 106 | *Örnekler* 107 | 108 | [source,java] 109 | ---- 110 | LocalDateTime now = LocalDateTime.now(); 111 | 112 | LocalDateTime dateTime = 113 | LocalDateTime.of(2014, Month.JANUARY, 3, 4, 5, 45); 114 | 115 | dateTime.getYear(); // 2014 116 | dateTime.getMonth(); // JANUARY 117 | dateTime.getDayOfMonth(); // 3 118 | dateTime.getHour(); // 4 119 | dateTime.getMinute(); // 5 120 | dateTime.getSecond(); // 45 121 | 122 | // LocalDateTime2LocalDate ve LocalDateTime2LocalTime 123 | LocalDate date = dateTime.toLocalDate(); 124 | LocalTime time = dateTime.toLocalTime(); 125 | 126 | dateTime 127 | .minusDays(3) 128 | .plusYears(3) 129 | .plusMinutes(3) 130 | .minusWeeks(5) 131 | .plusSeconds(2) 132 | .plus(3, ChronoUnit.DECADES) 133 | .minus(3, ChronoUnit.DECADES); 134 | ---- 135 | 136 | === ZoneId 137 | 138 | ZoneId sınıfı, dünya üzerindeki saat dilimlerinin Java taraflı nesnel karşılığını temsil için oluşturulan yeni bir Java 8 bileşenidir. 139 | 140 | Java 8 için tüm saat dilimlerinin listelenmesi için `ZoneId` sınıfının `getAvailableZoneIds` metodu kullanılabilmektedir. Örneğin aşağıdaki kod, tüm saat dilimlerini sıralı olarak listelemektedir. 141 | 142 | [source,java] 143 | ---- 144 | Set zones = ZoneId.getAvailableZoneIds(); 145 | 146 | zones.stream().sorted().forEach(System.out::println); 147 | ---- 148 | 149 | ---- 150 | … 151 | Africa/Abidjan 152 | Africa/Accra 153 | Africa/Addis_Ababa 154 | … 155 | America/Argentina/Tucuman 156 | America/Argentina/Ushuaia 157 | America/Aruba 158 | America/Asuncion 159 | … 160 | Asia/Istanbul 161 | Asia/Jakarta 162 | Asia/Jayapura 163 | … 164 | Etc/GMT+12 165 | Etc/GMT+2 166 | Etc/GMT+3 167 | … 168 | Europe/Isle_of_Man 169 | Europe/Istanbul 170 | Europe/Jersey 171 | … 172 | ---- 173 | 174 | O anki çalışılan makinadaki saat dilimi için ZoneId sınıfının systemDefault metodu kullanılabilir. 175 | 176 | [source,java] 177 | ---- 178 | ZoneId.systemDefault(); // Europe/Athens 179 | ---- 180 | 181 | JVM varsayılan saat dilimini mevcut işletim sistemi üzerinden almaktadır. Eğer istenirse mevcut Java sanal makinesinin varsayılan saat dilimi `-Duser.timezone=