Stream API (J2SE8) mimarisi ve kullanım teknikleri: Bölüm-1

Herkese merhaba;

Bu makale ile Java 8 standartı olan stream api mimarisi hakkında sizlere bilgi vermeye çalışacağım. Öncelikle stream api ile ilgili bilinmesi gereken birtakım temel özelliklere değinelim:

Amaç: Yığınsal da denilen dizileri listeleri düzenlemey yarayan bir apidir. Bunlara örnek olarak primitive veya obje diziler olan int[] veya String[] gibi modeller veya JCF de bahsi geçen Collection interface inden genişleyen ArrayList, HashSet, LinkedHashMap, List, Set vs tüm bu örnek tiplere müdehaleyi kolaylaştıran bir API dir.

Örnek kullanım biçimlerine değinecek olur isek temel dizi bileşenlerinden başlayabiliriz:

Önce temel bir dizi bileşeni oluşturalım:

Ön izlem:
String listenin Lambda ve Stream api kullanılarak yazdırılması.
Şimdi diziyi Stream e çevirelim: Şimdi son olarak Stream api si ile gelen forEach döngüsü ile verileri görüntüleyelim:
islemdizisi.forEach(basliklar ->{
			System.out.println("Başlık:"+ basliklar);
			
		}); 
Burada anlamamız gereken birtakım nesneler ve komutlar var: 1. Stream(): Bu bir interface dir ve BaseStream i extend etmiştir. Generik bir yapıya sahiptir. Stream objelerinin barındırılması için nesnemizi bu tip ile tanımlıyoruz. 2. ForEach: Bu komut bir stream içinde elemanlar arası döngü ile geçişi sağlamaktadır. İçinde Lambda tanımlama biçimlerini destekleyen bir döngü modelidir. 3. Basliklar ->{ System.out.println(“Başlık:”+ Basliklar);} : ForEach ile listeden gelen değişken tipini otomatik olarak tanımlar ve bu kullanım biçimi ile 1 değişken alır kendi scope una ( {} alanı : scope). Döngü ile her dönüşte içindeki liste elemanı Baslik değişkenine atanır. İçeride ise bu değişken kullanılır. Inner Class veya Pojo ile Kullanımı: Öncelikle StreamOrnek.class ismi ile bir sınıf oluşturuyorum, içine de class tanımı yapıyorum:
class StreamOrnek {
	public class ornekPojo{
		private Long id;
		private String ad;
		private String soyad;
		private String tc;
		public Long getId() {
			return id;
		}
		public void setId(Long id) {
			this.id = id;
		}
		public String getAd() {
			return ad;
		}
		public void setAd(String ad) {
			this.ad = ad;
		}
		public String getSoyad() {
			return soyad;
		}
		public void setSoyad(String soyad) {
			this.soyad = soyad;
		}
		public String getTc() {
			return tc;
		}
		public void setTc(String tc) {
			this.tc = tc;
		}
       }
}
İç sınıflar (inner class) erişim için kullanılan yöntemlerden biri şöyledir:
StreamOrnek.ornekPojo obj1  =  new StreamOrnek().new ornekPojo();
Burada önce Ana sınıf yazılır ardından alt sınıf adı belirtilir. (Android de R classı örneği gibi.) Şimdi bu sınıflardan örnek objeler yaratalım:
		StreamOrnek.ornekPojo obj1  =  new StreamOrnek().new ornekPojo();
		obj1.setId(1L);
		obj1.setAd("Selçuk");
		obj1.setSoyad("Uzunsoy");
		obj1.setTc("12345678910");
	
		StreamOrnek.ornekPojo obj2  =  new StreamOrnek().new ornekPojo();
		obj2.setId(2L);
		obj2.setAd("R2D2");
		obj2.setSoyad("Starwars");
		obj2.setTc("1010101010101010");
Yarattığımız bu objeleri şimdi diziye atalım ve bu diziyi stream e çevirelim: Dönüşüm zamanı : ) Stream içindeki sınıf tanımlamasına odaklanın: Stream burada Stream içinde artık inner class ın olduğunu generik tip tanımlama ile belirtiyoruz. Bu tip tanımlandıktan sonra foreach ile bu nesneleri yazdırabilirim:
islemdizisi_pojo.forEach(obj ->{
			System.out.println("ID:"+ obj.getId());
			System.out.println("İsim:"+ obj.getAd());
			System.out.println("Soyisim:"+ obj.getSoyad());
			System.out.println("TC:"+ obj.getTc());
});
Buradaki obj ifadesi otomatik olarak StreamOrnek.ornekPojo ya cast edilecek. (Lambda ifadeleri ) Bu sayede tip güvenliği sağlanmı şoluyor. Peki bunu başka şekilde nasıl yazdırabiliriz ? Eğer bir method :: “iki nokta üst üste operatörü” ile bir sınıftan çağırılır ise method ismini verdiğimizde, parametresi giden obje türünden olan method çağırılacaktır. Mesela: islemdizisi_pojo.forEach(StreamOrnek::yazdir); StreamOrnek içinde yazdır adında bir parametreli bir method tanımlıyoruz:
	public static void yazdir(StreamOrnek.ornekPojo veri){		
		System.out.println("Bilgi Pojo kullanımı:"+veri.getAd());
	}
Peki şimdi objeyi listeye koyduk ama içinden bir seçim yapmak istiyorsam ne yapmalıyım ? Mesela objenin bir parametresi kayıt edilen ismi veriyor. Bu bana istediğim ismi arama şansı veriyor mu acaba ? Burada liste içinde kayıtlı objelerden adında R2D2 olan objeler gelmesi için Predicate functional Interface inden faydalanıyoruz. Bu tip bir koşul Lambda betiği yazarak filter komutu aracığı ile liste içindeki verileri süzüyoruz. Şimdi sıra yazdırmada:
filtrelenmis_islemdizisi_pojo.forEach(StreamOrnek::yazdir);
yazdır methodunun parametresi , kullandığımız objenin tipindeydi ! Stream tek kullanımlık bir yapıya sahiptir. Bir kere kullanıldığında yeniden stream yaratmanız gerekir:
islemdizisi_values = dizi_values.stream();
Dizi içindeki istediğim değer aralığını Predicate ile belirliyorum:
Ön izlem:
Sayısal içerikli bir listenin Stream filtre kullanılarak veri setinin kısıtlandırılması.
Burada 6 dan küçük değerler filtrelenmesi için ön hazırlık yapıyorum. filter komutunu kullanarak gerekli şekilde eleme işlemini yaptırıyoruz. Şimdi method referansı ile otomatik olarak yazdırmak için Integer parametresi alan bir yazdır methodu yazıyorum:
	public static void yazdir(Integer veri){		
		System.out.println("Bilgi"+veri);
	}
Bu methodu forEach içinde kullarak otomatik olarak çağırılmasını sağlıyorum:
filtrelenmis_islemdizisi_values.forEach(StreamOrnek::yazdir);
Eğer verilerin tekrarlı olanlarını listeden elemek istiyor isem, distinct komutunu kullanmalıyım: Eğer otomatik olarak küçükten büyüğe doğru ASC sıralama bazlı bir çıktı almak istiyor isem: NOT: Eğer sıralamayı obje özelliklerine göre yapmak istiyor iseniz Comparator Interface inden yararlanmalısınız. Eğer gelen veriler içinden kısıtlı sayıda gösterim yapmayı istiyor iseniz limit komutu tam size göre: Eğer listesinin açık aralıklı adedini “[ ) küme gösterimi” istiyor iseniz count kullanılır: Stream api yapısının oldukça fazla özelliği mevcut ama ben genelde en çok kullanılan özelliklerine ilk Stream api makalemde değinmiş oldum. Umarım yararlı bulmuşsunuzdur. iyi çalışmalar, bol tekrarlı günler 🙂
  Örnek kodları indir:
  Proje Dosyası
GIT Repository:
Adres: https://github.com/uzunsoy/stream_api_bolum_1.git

IDE-Eclipse 1

Eclipse ile Java Projesi

Merhaba arkadaşlar, bugün sizlere Eclipse ile yeni bir Java projesini nasıl oluşturduğumuzu ve hangi ayarların ne işe yaradığını anlatacağım. Umarım faydalı olur…

Haydi başlayalım:

Eclipse ilk açıldığında size çalışma alnının nereye kurulacağını sorar. Siz silinmeyeceğinden emin olacağınız bir klasörün kök dizini ile birlikte tam adresini alıp size sorulan konumu gereken text kutucuğuna yapıştırın.(Şekil.1)

Eclipse açıldığında sorulan çalışma alanının konumu.
Şekil.1. Eclipse açıldığında sorulan çalışma alanının konumu.

Gereken konum verildikten hemen sonra açılan ekranda bir karşılama teması belirir. O temayı çarpı işaretinin olduğu alandan kapatabilirsiniz. Şimdi karşınıza bir çalışma alanı gelmiş bulunuyor. (Şekil.2)

Şekil.2 Eclipse çalışma alanı (Şu anda Java EE Perspektifinde)
Şekil.2 Eclipse çalışma alanı (Şu anda Java EE Perspektifinde)

Eclipse’de birden fazla arayüz tanımı mevcuttur. Bu arayüzler yapılacak projelerin tipine göre veya icra edilecek görevlere göre değişkenlik göstermektedir. Mesela Java Enterprise Edition  (J2EE) Perspektifin de kullanılan araçlar farklı olduğu için arayüz size bu araçlar ile gelir. Debug perspektifinde satır satır analiz yapacağınız için tüm değişkenlerin değerlerinin gösterildiği bir arayüz ve proje hakkında bilgi alabileceğiniz farklı pencereler ile sizleri bilgilendirir. Bu aşamada JavaEE perspektifi aktiftir. Bu perspektifte yeni bir proje oluşturmak için;

  1. File:New:Other seçilir.
Şekil.3. Yeni proje oluşturmak için gereken adım.
Şekil.3. Yeni proje oluşturmak için gereken adım.

Ardından açılan ekranda “Java Projesi” seçilir. Birden fazla seçim imkanı mevcut. Bu imkanlardan en çok kullanılan olan “Dynamic Web Project” seçeneğidir ama şu anda Java Projesini seçeceğiz.

Şekil.4. Dinamik Web Projesi
Şekil.4. Dinamik Web Projesi
Şekil.5. Java Projesi Seç
Şekil.5.Java Projesi

Bu aşamadan sonra Next deyip ilerleyelim.

Şekil.6. İleri gidelim
Şekil.6. İleri gidelim

Bu alanlarda bulunan:

  1. Proje Name: Projemizin adı olacak.
  2. “Use Default Location” checkBox ı ile projenin gerçek disk teki konumunu verilir.
  3. JRE ile sistemde kurulu olan hangi Java sürümü tercih edilecek ise o seçilir.
  4. Project Layout ile java nın src ve bin ana klasörlerinin dışında kök klasör olarak ne olacak ise onlar belirlenir.
  5. Working set alanında ise çalışma alanının revize edilmesi sağlanır.

 

Şekil.7. Yeni proje oluşum aşaması.
Şekil.7. Yeni proje oluşum aşaması.

Bu alanda en önemli kısım “Libraries” kısmıdır. Projede kullanılacak kütüphaneler bu alandan yüklenir (Eğitim videosuna atıfta bulunulacaktır). Finish dendikten sonra en temel proje yapısı karşınıza çıkacaktır. Çıkmadan hemen önce eğer Java Perspektifinde değilseniz “Java Perspektifi” ne geçiş için onay ister. Onay verildiği taktirde geçiş yapılır. Karşınıza yeni proje oluşmuş şekilde çıkacaktır.

Şekil.8. Yeni projenin gösterimi.
Şekil.8. Yeni projenin gösterimi.

Eclipse temel manada bu şekilde proje oluşturur ve her tip projeye bağlı olarak farklı ekranları kullanıma çağırır. Bu sebepten ötürü birden fazla ekran ile karşılaşırız.

Başarılar dilerim, bol kodlu günler …

 

Java & IDE

Java & IDE

Java yapısal olarak nesne odaklı mimariyi benimseyen, her aşamada nesne odaklı tasarım için yardımcı araçların kullanımınıza sunulduğu yüksek seviyeli modern bir dildir. Her dilde olduğu gibi Java ‘da kendine özgü IDE’leri olan bir geliştirme çatısıdır (framework). En yaygın olan IDE’ler şöyledir:

  • Eclipse
  • Netbeans
  • JDeveloper
  • IntelliJ

Yukarıda bahsi geçen IDE’ler size Java dilinde kodlama yaparken uyulması gereken kurallara riayet etmenize olanak verir ve gereken tasarım modellerini de biçimlendirmenizi sağlar. Ben bir çok projem de Eclipse kullanıyorum ama bir takım web odaklı önde gelen projede NetBeans tercih ettim. Bu kullanım kolaylığı ve arayüzün daha kullanıcı dostu (user-friendly) olmasından ötürü olmasıdır. Her iki IDE de eklenti üzerine kurulmuş bir mimariye sahiptir. Yakın zamana kadar Netbeans eklentileri desteklemiyordu ama trend bu alana doğru gittiği için mantıklı olan yolu tercih etti diyebiliriz. JDeveloper ile Sağlık Bakanlığının önemli bir projesinde tanıştım. Oldukça sade ve kullananların bir çoğunun pekde hoşnut olmadığı bir IDE. Şahsen Oracle tarafından doğrudan tasarlanmış olması ve destekleniyor olması bence büyük avantaj lakin hala biraz kullanıcı dostu olmaktan uzak. Bunun yanı sıra Oracle’ın ünlü çatısı ADF kodlamak istiyor iseniz size hazır birçok araç ile gelmektedir. Kütüphane entegre etme aşamaları eclipse ile benzerlik gösteriyor. Yazım alanlarının benzerliği de dikkat çekici. IntelliJ ise Android Studio’nun üzerine kurulduğu yapı olması sebebiyle tanıştığım bir IDE dir. Oldukça hoş bir arayüzü mevcut yani kullanıcı dostu görünüyor. Bir çok alanda Eclipse de debelendiğim süreçlerde bir iki arayüzle işimi çözüme ulaştırıyorum. Belki çok yüzeysel gelmiş olabilir yazdıklarım ama derinlemesine inceleme sürecindeyim ve yakın zamanda karşılaştırmalı bir makale ile karşınıza çıkacağım.

Teşekkürler, bol kodlu günler….