🚀 BAŞTAN SONA JAVA DİLİ BÖLÜM-20 (FİNAL): Optional, Multithreading Giriş ve Katmanlı Banka Otomasyon Projesi 🏆

🚀 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::println);
}
}

---

📊 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

 
Yanıt yazmak için giriş yapmalısınız
Forum özelliklerini kullanmak ve Level 2 üyelik satın almak için hesabınıza giriş yapın.
135,050Konular
3,297,719Mesajlar
326,237Kullanıcılar
thekral21Son Üye
Üst Alt