-
Sadrazamv4
instagram:sadrazam.spy Tg:Sadrazamv4
🚀 BAŞTAN SONA JAVA DİLİ BÖLÜM-20 (FİNAL): Optional, Multithreading Giriş ve Katmanlı Banka Otomasyon Projesi 🏆
Selamlar dostlar! 👋
12 haftalık/20 bölümlük dev Java Dili serimizin muhteşem **Final Bölümüne** hoş geldiniz! 🎉
İlk bölümden bu yana JVM mimarisinden başlayarak değişkenleri, karar yapılarını, döngüleri, metotları, Nesne Yönelimli Programlamanın (OOP) 4 temel direğini (Encapsulation, Inheritance, Polymorphism, Abstraction), Collections Framework (`List`, `Set`, `Map`), Exception Handling, Generics, Lambda Expressions ve Stream API konularını eksiksiz işledik.
Bu final bölümünde ise Java dünyasının iki kritik konusu olan **`Optional<T>`** ve **Multithreading** kavramlarına değinecek, ardından tüm öğrendiklerimizi harmanlayan **Katmanlı Mimari (Layered Architecture)** prensiplerine uygun bir **Banka Otomasyon Projesi** geliştireceğiz! 🚀
---
📌 1. `NullPointerException` Belasına Son: `Optional<T>` 🛡️
Java geliştiricilerinin en çok karşılaştığı hata `NullPointerException` (NPE) hatasıdır. Java 8 ile gelen `Optional<T>` sınıfı, bir değerin `null` olabileceğini açıkça belirten bir konteyner yapısı sunar.
### Temel Metotlar:
• `Optional.ofNullable(deger)`: Değer null da olsa güvenle sarar.
• `isPresent()` / `isEmpty()`: Değerin varlığını kontrol eder.
• `orElse(varsayilan)`: Değer null ise varsayılan bir değer döner.
• `orElseThrow()`: Değer yoksa belirlediğiniz bir exception'ı fırlatır.
import java.util.Optional;
public class Main {
public static Optional<String> kullaniciBul(int id) {
if (id == 1) return Optional.of("Ahmet Yılmaz");
return Optional.empty(); // null yerine boş Optional dönüyoruz
}
public static void main(String[] args) {
Optional<String> kullanici = kullaniciBul(2);
// Değer varsa yazdır, yoksa varsayılan metni kullan
String isim = kullanici.orElse("Bilinmeyen Kullanıcı");
System.out.println("Kullanıcı: " + isim);
}
}
---
🧵 2. Çoklu İş Parçacığı Yönetimi: Multithreading Giriş 🧵
Java, aynı anda birden fazla görevi eşzamanlı (concurrent) olarak yürütmemize olanak tanıyan güçlü bir **Multithreading** altyapısına sahiptir.
Bir thread oluşturmanın 2 temel yolu vardır:
1. `Thread` sınıfından türetmek (`extends Thread`).
2. `Runnable` arayüzünü uygulamak (`implements Runnable`) — *Best Practice!*
### `Runnable` ve Lambda İle Thread Oluşturma:
public class Main {
public static void main(String[] args) {
// Lambda kullanarak Runnable görevi tanımlama
Runnable gorev = () -> {
for (int i = 1; i <= 3; i++) {
System.out.println(Thread.currentThread().getName() + " çalışıyor: " + i);
try {
Thread.sleep(500); // 500 milisaniye bekletme
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread thread1 = new Thread(gorev, "İş parçacığı-1");
Thread thread2 = new Thread(gorev, "İş parçacığı-2");
thread1.start(); // Thread başlatma (run() doğrudan çağrılmaz!)
thread2.start();
}
}
---
🏗️ 3. FİNAL PROJESİ: Katmanlı Mimari İle Banka Otomasyonu 🏦
Öğrendiğimiz tüm OOP, Collection, Stream API, Exception ve Optional yapılarını birleştiren temiz bir konsol otomasyonu yazıyoruz.
### A. Model Katmanı (`Hesap.java`)
public class Hesap {
private final String hesapNo;
private final String sahidi;
private double bakiye;
public Hesap(String hesapNo, String sahidi, double bakiye) {
this.hesapNo = hesapNo;
this.sahidi = sahidi;
this.bakiye = bakiye;
}
public String getHesapNo() { return hesapNo; }
public String getSahidi() { return sahidi; }
public double getBakiye() { return bakiye; }
public void paraYatir(double miktar) {
if (miktar > 0) this.bakiye += miktar;
}
public boolean paraCek(double miktar) {
if (miktar > 0 && miktar <= bakiye) {
this.bakiye -= miktar;
return true;
}
return false;
}
@Override
public String toString() {
return "Hesap No: " + hesapNo + " | Sahip: " + sahidi + " | Bakiye: " + bakiye + " TL";
}
}
### B. Servis Katmanı (`BankaServisi.java`)
import java.util.*;
import java.util.stream.Collectors;
public class BankaServisi {
private final Map<String, Hesap> hesaplar = new HashMap<>();
public void hesapEkle(Hesap hesap) {
hesaplar.put(hesap.getHesapNo(), hesap);
System.out.println("Hesap başarıyla tanımlandı: " + hesap.getHesapNo());
}
public Optional<Hesap> hesapBul(String hesapNo) {
return Optional.ofNullable(hesaplar.get(hesapNo));
}
public void paraYatir(String hesapNo, double miktar) {
hesapBul(hesapNo).ifPresentOrElse(
h -> {
h.paraYatir(miktar);
System.out.println("İşlem Başarılı! Güncel Bakiye: " + h.getBakiye() + " TL");
},
() -> System.out.println("HATA: Hesap bulunamadı!")
);
}
// Stream API ile Zengin Müşterileri Filtreleme
public List<Hesap> zenginMusterileriGetir(double limit) {
return hesaplar.values().stream()
.filter(h -> h.getBakiye() >= limit)
.sorted(Comparator.comparingDouble(Hesap::getBakiye).reversed())
.collect(Collectors.toList());
}
}
### C. Ana Çalıştırma Katmanı (`Main.java`)
public class Main {
public static void main(String[] args) {
BankaServisi banka = new BankaServisi();
System.out.println("==================================================");
System.out.println(" ☕ JAVA BANKA OTOMASYON SİSTEMİNE HOŞ GELDİNİZ");
System.out.println("==================================================\n");
// 1. Hesaplar Oluşturuluyor
banka.hesapEkle(new Hesap("TR101", "Ahmet Yılmaz", 15000.0));
banka.hesapEkle(new Hesap("TR102", "Ayşe Kaya", 45000.0));
banka.hesapEkle(new Hesap("TR103", "Mehmet Demir", 80000.0));
System.out.println("\n--- Para Yatırma İşlemi ---");
banka.paraYatir("TR101", 5000.0);
System.out.println("\n--- Stream API İle Varlıklı Müşteri Analizi (Limit: 20.000 TL) ---");
List<Hesap> VIPMusteriler = banka.zenginMusterileriGetir(20000.0);
VIPMusteriler.forEach(System.out:
rintln);
}
}
---
📊 4. Serinin Genel Kazanım Tablosu 📋
| Bölüm Aralığı | Temel Kazanımlar |
| :--- | :--- |
| **Bölüm 1 - 5** | JDK/JVM/JRE, Değişkenler, Operatörler, `if/else`, `switch`, Döngüler, Metotlar, Overloading |
| **Bölüm 6 - 11** | OOP Mantığı, Sınıf/Nesne, Constructors, Encapsulation, Inheritance, Polymorphism, Abstraction |
| **Bölüm 12 - 15** | Diziler, `ArrayList`, `LinkedList`, `HashSet`, `TreeSet`, `HashMap`, `TreeMap`, `hashCode/equals` |
| **Bölüm 16 - 20** | Exception Handling, Custom Exception, Generics, Lambda, Stream API, `Optional`, Multithreading |
---
🎉 TEBRİKLER! SERİYİ BAŞARIYLA TAMAMLADINIZ! 🎉
Baştan Sona Java Dili rehber serisini eksiksiz bir şekilde bitirdiniz!
Artık nesne yönelimli mimarileri rahatça kurgulayabilen, koleksiyonları ve Stream API'yi etkin şekilde kullanan, modüler, güvenli ve modern Java k
odu yazabilen yetkin bir Java Developer yolundakiniz! ☕✨
Sorularınızı, görüşlerinizi ve projelerinizi paylaşmayı unutmayın.
JVM'iniz hızlı, kodlarınız hatasız çalışsın! Kodla kalın! ☕🚀
Selamlar dostlar! 👋
12 haftalık/20 bölümlük dev Java Dili serimizin muhteşem **Final Bölümüne** hoş geldiniz! 🎉
İlk bölümden bu yana JVM mimarisinden başlayarak değişkenleri, karar yapılarını, döngüleri, metotları, Nesne Yönelimli Programlamanın (OOP) 4 temel direğini (Encapsulation, Inheritance, Polymorphism, Abstraction), Collections Framework (`List`, `Set`, `Map`), Exception Handling, Generics, Lambda Expressions ve Stream API konularını eksiksiz işledik.
Bu final bölümünde ise Java dünyasının iki kritik konusu olan **`Optional<T>`** ve **Multithreading** kavramlarına değinecek, ardından tüm öğrendiklerimizi harmanlayan **Katmanlı Mimari (Layered Architecture)** prensiplerine uygun bir **Banka Otomasyon Projesi** geliştireceğiz! 🚀
---
📌 1. `NullPointerException` Belasına Son: `Optional<T>` 🛡️
Java geliştiricilerinin en çok karşılaştığı hata `NullPointerException` (NPE) hatasıdır. Java 8 ile gelen `Optional<T>` sınıfı, bir değerin `null` olabileceğini açıkça belirten bir konteyner yapısı sunar.
### Temel Metotlar:
• `Optional.ofNullable(deger)`: Değer null da olsa güvenle sarar.
• `isPresent()` / `isEmpty()`: Değerin varlığını kontrol eder.
• `orElse(varsayilan)`: Değer null ise varsayılan bir değer döner.
• `orElseThrow()`: Değer yoksa belirlediğiniz bir exception'ı fırlatır.
import java.util.Optional;
public class Main {
public static Optional<String> kullaniciBul(int id) {
if (id == 1) return Optional.of("Ahmet Yılmaz");
return Optional.empty(); // null yerine boş Optional dönüyoruz
}
public static void main(String[] args) {
Optional<String> kullanici = kullaniciBul(2);
// Değer varsa yazdır, yoksa varsayılan metni kullan
String isim = kullanici.orElse("Bilinmeyen Kullanıcı");
System.out.println("Kullanıcı: " + isim);
}
}
---
🧵 2. Çoklu İş Parçacığı Yönetimi: Multithreading Giriş 🧵
Java, aynı anda birden fazla görevi eşzamanlı (concurrent) olarak yürütmemize olanak tanıyan güçlü bir **Multithreading** altyapısına sahiptir.
Bir thread oluşturmanın 2 temel yolu vardır:
1. `Thread` sınıfından türetmek (`extends Thread`).
2. `Runnable` arayüzünü uygulamak (`implements Runnable`) — *Best Practice!*
### `Runnable` ve Lambda İle Thread Oluşturma:
public class Main {
public static void main(String[] args) {
// Lambda kullanarak Runnable görevi tanımlama
Runnable gorev = () -> {
for (int i = 1; i <= 3; i++) {
System.out.println(Thread.currentThread().getName() + " çalışıyor: " + i);
try {
Thread.sleep(500); // 500 milisaniye bekletme
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread thread1 = new Thread(gorev, "İş parçacığı-1");
Thread thread2 = new Thread(gorev, "İş parçacığı-2");
thread1.start(); // Thread başlatma (run() doğrudan çağrılmaz!)
thread2.start();
}
}
---
🏗️ 3. FİNAL PROJESİ: Katmanlı Mimari İle Banka Otomasyonu 🏦
Öğrendiğimiz tüm OOP, Collection, Stream API, Exception ve Optional yapılarını birleştiren temiz bir konsol otomasyonu yazıyoruz.
### A. Model Katmanı (`Hesap.java`)
public class Hesap {
private final String hesapNo;
private final String sahidi;
private double bakiye;
public Hesap(String hesapNo, String sahidi, double bakiye) {
this.hesapNo = hesapNo;
this.sahidi = sahidi;
this.bakiye = bakiye;
}
public String getHesapNo() { return hesapNo; }
public String getSahidi() { return sahidi; }
public double getBakiye() { return bakiye; }
public void paraYatir(double miktar) {
if (miktar > 0) this.bakiye += miktar;
}
public boolean paraCek(double miktar) {
if (miktar > 0 && miktar <= bakiye) {
this.bakiye -= miktar;
return true;
}
return false;
}
@Override
public String toString() {
return "Hesap No: " + hesapNo + " | Sahip: " + sahidi + " | Bakiye: " + bakiye + " TL";
}
}
### B. Servis Katmanı (`BankaServisi.java`)
import java.util.*;
import java.util.stream.Collectors;
public class BankaServisi {
private final Map<String, Hesap> hesaplar = new HashMap<>();
public void hesapEkle(Hesap hesap) {
hesaplar.put(hesap.getHesapNo(), hesap);
System.out.println("Hesap başarıyla tanımlandı: " + hesap.getHesapNo());
}
public Optional<Hesap> hesapBul(String hesapNo) {
return Optional.ofNullable(hesaplar.get(hesapNo));
}
public void paraYatir(String hesapNo, double miktar) {
hesapBul(hesapNo).ifPresentOrElse(
h -> {
h.paraYatir(miktar);
System.out.println("İşlem Başarılı! Güncel Bakiye: " + h.getBakiye() + " TL");
},
() -> System.out.println("HATA: Hesap bulunamadı!")
);
}
// Stream API ile Zengin Müşterileri Filtreleme
public List<Hesap> zenginMusterileriGetir(double limit) {
return hesaplar.values().stream()
.filter(h -> h.getBakiye() >= limit)
.sorted(Comparator.comparingDouble(Hesap::getBakiye).reversed())
.collect(Collectors.toList());
}
}
### C. Ana Çalıştırma Katmanı (`Main.java`)
public class Main {
public static void main(String[] args) {
BankaServisi banka = new BankaServisi();
System.out.println("==================================================");
System.out.println(" ☕ JAVA BANKA OTOMASYON SİSTEMİNE HOŞ GELDİNİZ");
System.out.println("==================================================\n");
// 1. Hesaplar Oluşturuluyor
banka.hesapEkle(new Hesap("TR101", "Ahmet Yılmaz", 15000.0));
banka.hesapEkle(new Hesap("TR102", "Ayşe Kaya", 45000.0));
banka.hesapEkle(new Hesap("TR103", "Mehmet Demir", 80000.0));
System.out.println("\n--- Para Yatırma İşlemi ---");
banka.paraYatir("TR101", 5000.0);
System.out.println("\n--- Stream API İle Varlıklı Müşteri Analizi (Limit: 20.000 TL) ---");
List<Hesap> VIPMusteriler = banka.zenginMusterileriGetir(20000.0);
VIPMusteriler.forEach(System.out:
}
}
---
📊 4. Serinin Genel Kazanım Tablosu 📋
| Bölüm Aralığı | Temel Kazanımlar |
| :--- | :--- |
| **Bölüm 1 - 5** | JDK/JVM/JRE, Değişkenler, Operatörler, `if/else`, `switch`, Döngüler, Metotlar, Overloading |
| **Bölüm 6 - 11** | OOP Mantığı, Sınıf/Nesne, Constructors, Encapsulation, Inheritance, Polymorphism, Abstraction |
| **Bölüm 12 - 15** | Diziler, `ArrayList`, `LinkedList`, `HashSet`, `TreeSet`, `HashMap`, `TreeMap`, `hashCode/equals` |
| **Bölüm 16 - 20** | Exception Handling, Custom Exception, Generics, Lambda, Stream API, `Optional`, Multithreading |
---
🎉 TEBRİKLER! SERİYİ BAŞARIYLA TAMAMLADINIZ! 🎉
Baştan Sona Java Dili rehber serisini eksiksiz bir şekilde bitirdiniz!
Artık nesne yönelimli mimarileri rahatça kurgulayabilen, koleksiyonları ve Stream API'yi etkin şekilde kullanan, modüler, güvenli ve modern Java k
odu yazabilen yetkin bir Java Developer yolundakiniz! ☕✨
Sorularınızı, görüşlerinizi ve projelerinizi paylaşmayı unutmayın.
JVM'iniz hızlı, kodlarınız hatasız çalışsın! Kodla kalın! ☕🚀
🔒 Bu içeriği görmek için giriş yapın