Java Programlama Dili
Bu doküman, Java programlama dilinin temel kavramlarını, sözdizimini ve önemli yapılarını detaylı bir şekilde içerir.
Giriş ve Temel Kavramlar
build Derleme ve Çalıştırma
Java platform bağımsızdır. Yazılan kod önce derlenir (bytecode'a çevrilir), sonra JVM (Java Virtual Machine) üzerinde çalıştırılır.
-
Dosya Uzantısı:
.java -
Derleme:
javac DosyaAdi.java→ DosyaAdi.class oluşur -
Çalıştırma:
java DosyaAdi
category Sınıf ve Nesne Kavramı
Java'da temel programlama elemanıdır. İlişkili verileri bir arada tutmak (Ad, soyad, yaş vb.) ve tek bir isimle erişmek için kullanılır. Bir kalıptır.
Sınıftan oluşturulan canlı örnektir. Sınıf bir kalıp ise, nesne o kalıptan üretilen üründür.
data_table Veri Tipleri (Primitive Types)
| Tip | Boyut | Açıklama |
|---|---|---|
byte |
1 byte | -128 ile 127 |
short |
2 byte | Küçük tam sayı |
int |
4 byte | Standart tam sayı |
long |
8 byte | Büyük tam sayı |
double |
8 byte | Varsayılan ondalıklı sayı |
boolean |
1 bit | true / false |
char |
2 byte | Unicode karakter ('A') |
Long sonuna L
String & Dönüşümler
numbers Tam Sayı → String
int sayi = 15;
String s1 = String.valueOf(sayi); // Yöntem 1
String s2 = sayi + ""; // Yöntem 2 (Pratik)
String s3 = Integer.toString(sayi); // Yöntem 3
abc String → Sayı
String str = "15.23";
float f1 = Float.valueOf(str); // Yöntem 1
float f2 = Float.parseFloat(str); // Yöntem 2
abc String Metotları (Cheat Sheet)
.length()
Karakter sayısı
.substring(i, j)
Parça al (i'den j'ye)
.contains("x")
İçeriyor mu? (T/F)
.equals("s")
Eşit mi? (T/F)
.trim()
Boşlukları temizle
.replace(a, b)
Değiştir
String s = " Java Candir ";
int boyut = s.length(); // 13
String temiz = s.trim(); // "Java Candir"
String parca = s.substring(1, 5); // "Java"
boolean varMi = s.contains("Can"); // true
String yeni = s.replace("a", "o"); // " Jovo Condir "
String metotları orijinal metni değiştirmez, YENİ bir String üretir. Sonucu tekrar atamazsanız (s = ...), değişiklik kaybolur.
Java'da stringlerin içeriğini kontrol etmek için ASLA == operatörünü kullanmayın. O sadece hafıza adresine bakar.
s1 == s2
Hatalı (Adres)
s1.equals(s2)
Doğru (İçerik)
Operatörler
calculate Aritmetik Operatörler
Java'da iki int bölünürse sonuç int olur (küsurat atılır).
question_mark Ternary (Şartlı Atama) Operatörü
Java'da 3 argüman alan tek operatördür: (Koşul) ? [Doğru] : [Yanlış]
int x = 11, y = 5, z = 0;
// Soru: x > y mi? Doğruysa x, yanlışsa y değerini z'ye ata.
z = (x > y) ? x : y; // Sonuç: 11
Erişim & Yetki
lock Erişim Belirleyiciler
key Anahtar Kelimeler
-
final
Değişkeni sabit yapar. İlk değer verildikten sonra değiştirilemez.
-
static
Sınıfa aittir. Nesne oluşturmadan (new demeden) sınıf adıyla çağrılabilir.
Math.sqrt(16)error Sık Yapılan Hatamainmetodu static'tir. Bu yüzden dışındaki (static olmayan) değişkenleri doğrudan kullanamaz.
Çözüm: Değişkeni destaticyap. -
void
Metodun geriye değer döndürmediğini belirtir.
Giriş / Çıkış İşlemleri
print Ekrana Yazdırma
System.out.print("Ondokuz Mayıs");
System.out.print("Üniversitesi");
System.out.printf("Samsun");
System.out.println("Mühendislik" + "Fak.");
System.out.print("Türkiye");
> Türkiye
| Karakter | Açıklama | Örnek |
|---|---|---|
%d | Tam sayı | 26 |
%c | Karakter | 'A' |
%s | String | "Ali" |
%f | Ondalıklı | 10.5 |
input Kullanıcıdan Veri Alma (Scanner)
import java.util.Scanner;
Scanner tara = new Scanner(System.in);
int sayi = tara.nextInt(); // Tam sayı al
Eğer nextInt()'den hemen sonra nextLine() kullanırsanız, Java enter tuşunu algılar ve String girmenize izin vermeden geçer!
int yas = scan.nextInt();
// Sorun: nextInt() 'Enter' karakterini almaz.
// Çözüm: Boşa bir okuma yaparak buffer'ı temizle!
scan.nextLine(); // <-- Buffer Temizleme (Fix)
String isim = scan.nextLine(); // Artık çalışır
Kontrol Yapıları
If - Else Blokları
if (yas < 18) {
System.out.println("Genç");
} else {
System.out.println("Yetişkin");
}
Switch - Case
Float/Double OLMAZswitch (gun) {
case 1: System.out.println("Pzt"); break;
default: System.out.println("Hata");
}
break yazmazsan, doğru case çalıştıktan sonra DURMAZ, alttakileri de çalıştırır.
Döngüler
For Döngüsü
Belirli sayıda tekrar için idealdir.
While
Koşul başta kontrol edilir. 0 kez çalışabilir.
Do-While
En az 1 kez çalışması garanti edilir.
while döngüsü içinde sayacı artırmayı unutursan (örn: i++ yoksa), döngü asla bitmez ve program kilitlenir!
label Etiketli Break (Loop'ları Kırmak)
disDongu:
for(int i=0; i<5; i++) {
for(int j=0; j<5; j++) {
if(j == 3) break disDongu; // En dıştaki döngüyü kırar
}
}
Bellek Yönetimi
Stack (Yığıt)
Metot çağrıları ve yerel (primitive) değişkenler burada tutulur. Hızlıdır, otomatik temizlenir.
Heap (Yığın)
new ile oluşturulan Nesneler burada yaşar. Stack'teki referanslar, burayı işaret eder.
Garbage Collector (Çöp Toplayıcı)
Heap bellekte referansı kalmayan (kimsenin göstermediği) nesneleri otomatik temizler.
finalize()
Nesne silinmeden hemen önce JVM tarafından çağrılan metottur.
System.gc()
Çöp toplayıcıyı çalışmaya davet eder (Garanti değildir).
Araba a1 = a2; yaparsan yeni araba oluşmaz! İki değişken de AYNI arabayı gösterir.
Paket ve Import
-
folder_open
Paket (Package)
Kodun en başına
package com.ornek;şeklinde yazılır. -
download
Import
import java.util.*;(Tümünü dahil et) veya tek tek.
Javadoc
/**
* Bu sınıf matematik işlemleri yapar.
* @author Emiran
* @param sayi İşlenecek değer
* @return Sonuç
*/
public int islemYap(int sayi) { ... }
Değişken Scope
Instance Variable
Sınıf içinde tanımlanır. Her nesne için ayrı bir kopyası vardır. Varsayılan değeri vardır (0, null vb).
Local Variable
Metot içinde tanımlanır. Sadece o blokta yaşar. İlk değer atanmak zorundadır!
int x = 0; gibi)
Diziler (Arrays)
Gelişmiş For (For-Each)
String[] isimler = {"Ali", "Veli"};
// Modern Yöntem
for(String isim : isimler) {
System.out.println(isim);
}
Dizi 5 elemanlıysa indeksler 0, 1, 2, 3, 4'tür.
dizi[5] çağırmak programı (Exception) patlatır!
Metotlar & Constructor
Method Overloading (Aşırı Yükleme)
Aynı isimde fakat farklı parametrelere (sayı veya tür) sahip metotlar tanımlanabilir.
public int topla(int a, int b) {
return a + b;
}
// Aynı isim, farklı parametre tipi
public double topla(double a, double b) {
return a + b;
}
Constructor (Yapılandırıcı)
Sınıftan nesne oluşturulduğunda ilk çalışan metottur. Return type yoktur.
Kritik: Eğer parametreli bir constructor yazarsanız, Java'nın verdiği otomatik boş constructor silinir.
public class Araba {
public Araba(int model) {
// Parametreli Yapıcı
}
}
// Araba a = new Araba(); // HATA! Boş yapıcı yok.
Araba b = new Araba(2023); // DOĞRU
Java dünyasının en meşhur hatasıdır. İçi boş (null) olan bir nesnenin metodunu çağırmaya çalışırsanız program çöker.
Örn: String s = null; s.length(); // PATLAR!
Koleksiyonlar (Collections)
category Koleksiyon Nedir?
Dizilerin (Array) aksine, boyutu dinamik olarak değişebilen, içinde nesneleri saklayan yapılardır. Veri ekledikçe büyür, sildikçe küçülür.
Sıralıdır. Aynı elemandan (duplicate) birden fazla olabilir.
ArrayList, LinkedList
Eşsizdir. Aynı elemandan SADECE 1 TANE olabilir (Duplicate yok).
HashSet, TreeSet
Anahtar-Değer (Key-Value) çifti saklar. Collection'dan türemez.
HashMap, TreeMap
ArrayList (List) Metotları
En Çok Kullanılanimport java.util.ArrayList;
ArrayList list = new ArrayList<>();
// Ekleme
list.add("Java");
list.add("Python");
list.add("Java"); // Tekrar EDEBİLİR
// Erişim
String dil = list.get(0); // "Java"
// Boyut & Silme
int size = list.size(); // 3
list.remove("Python"); // "Python" silinir
list.remove(0); // 0. indeks silinir
Set (Küme) Mantığı
Tekrar Yok!
HashSet: Hızlıdır ama sırasızdır (Rastgele dizer).
TreeSet: Yavaştır ama alfabetik/sayısal SIRALAR.
HashSet hs = new HashSet<>();
hs.add("Bursa");
hs.add("Ankara");
hs.add("Bursa"); // EKLENMEZ! (Duplicate)
System.out.println(hs);
// Çıktı: [Ankara, Bursa] (Sıra garanti değil)
TreeSet ts = new TreeSet<>(hs);
System.out.println(ts);
// Çıktı: [Ankara, Bursa] (Alfabetik Sıralı)
Iterator (Gezici)
Koleksiyonlar üzerinde güvenli bir şekilde dolaşmayı sağlar. Özellikle döngü sırasında eleman silmek için for-each yerine Iterator kullanılır.
.next()
Bir sonraki elemanı getirir.
.hasNext()
Sırada eleman var mı? (True/False)
.remove()
O anki elemanı güvenle siler (For-each'te bu patlar!)
Koleksiyonlar: Listeler
format_list_bulleted List (Liste) Yapısı
Dizilerin aksine boyutu dinamiktir. Yeni eleman eklendikçe otomatik büyür. Sıralı bir yapıdadır ve aynı elemandan birden fazla (duplicate) barındırabilir.
Arkaplanda Dizi (Array) kullanır. Veriye erişim (get) çok hızlıdır ama araya eleman ekleme/silme yavaştır (kaydırma gerekir).
Zincirleme yapıdadır. Her eleman bir sonrakini gösterir. Ekleme/Silme çok hızlıdır ama veriye erişim yavaştır (tek tek gezer).
Temel List Metotları
| Metot | Açıklama |
|---|---|
| add(e) | Listeye eleman ekler. |
| add(index, e) | Belirtilen sıraya elemanı ekler (Diğerlerini kaydırır). |
| remove(idnex) | İndisteki elemanı siler. |
| get(index) | İndisteki elemanı getirir (Okur). |
| set(index, e) | İndisteki elemanı günceller (Değiştirir). |
| size() | Eleman sayısını verir. |
| contains(e) | Eleman listede var mı? (True/False) |
| clear() | Tüm listeyi temizler. |
| addFirst() / addLast() | Başa veya sona ekler (Sadece LinkedList). |
ArrayList & Sıralama
Sortimport java.util.ArrayList;
import java.util.Collections; // Sıralama için şart!
ArrayList cars = new ArrayList<>();
cars.add("Volvo");
cars.add("BMW");
cars.add("Ford");
cars.add("Mazda");
// Listeyi Sırala (A-Z)
Collections.sort(cars);
for(String i : cars) {
System.out.println(i);
}
> Ford
> Mazda
> Volvo
LinkedList Özellikleri
Node YapısıLinkedList liste = new LinkedList<>();
liste.add("Portakal");
liste.add("Elma");
// Başa ve Sona Ekleme (LinkedList Özel)
liste.addFirst("Limon");
liste.addLast("Mandalina");
System.out.println(liste);
// [Limon, Portakal, Elma, Mandalina]
System.out.println("İlk: " + liste.getFirst());
System.out.println("Son: " + liste.getLast());
LinkedList, kuyruk (queue) yapısı kurmak için idealdir. İlk giren, ilk çıkar mantığı kolayca uygulanır.
Gelişmiş Yapılar: Queue (Kuyruk) & Stack (Yığın)
east Queue (FIFO)
First In First Out: İlk giren ilk hizmet alır (Banka sırası gibi).
| Metot | Görev |
|---|---|
| offer(e) | Sıraya ekle. |
| poll() | Baştakini al ve SİL. |
| peek() | Baştakine bak (SİLME). |
vertical_align_top Stack (LIFO)
Last In First Out: Son giren ilk çıkar (Üst üste konmuş kitaplar gibi).
LinkedList stack = new LinkedList<>();
stack.push("Kitap 1");
stack.push("Kitap 2");
System.out.println(stack.pop());
// Çıktı: Kitap 2 (Son giren)
settings_backup_restore Vector Sınıfı (Eski Tip)
ArrayList ile neredeyse aynıdır ama Thread-Safe (güvenli) olduğu için daha yavaştır. Ayrıca kapasite artışı farklıdır (Dolunca 2 katına çıkar).
| Vector Özel Metot | Açıklama |
|---|---|
| capacity() | Mevcut kapasiteyi verir (Boyut değil!). |
| firstElement() | İlk elemanı getirir (get(0)). |
| lastElement() | Son elemanı getirir. |
| copyInto(dizi) | Vektörü diziye kopyalar. |
Vector v = new Vector<>(5); // Başlangıç 5
v.add("Ali");
v.add("Veli");
System.out.println(v.size()); // 2 (Dolu)
System.out.println(v.capacity()); // 5 (Hafıza)
System.out.println(v.firstElement()); // "Ali"
Wrapper Classes
Kural
Koleksiyonlara int, double gibi ilkel tipler koyulamaz.
Onların Sınıf (Class) halleri kullanılır.
| İlkel Type | Wrapper Class |
|---|---|
| int | Integer |
| double | Double |
| char | Character |
| boolean | Boolean |
Maps (Haritalar) & Map.Entry
Anahtar-Değer çiftleri, İterasyon ve Veri Güncelleme.
public HashMap (Sırasız)
Verileri rastgele tutar. null anahtar alabilir. Anahtarlar ve değerler üzerinde ayrı ayrı gezilebilir.
HashMap hm = new HashMap<>();
hm.put("Turkiye", "Ankara");
hm.put("Fransa", "Paris");
hm.put("Rusya", "Moskava");
hm.put("Turkiye", "Bursa"); // Ankara SİLİNİR, Bursa olur!
// Sadece Anahtarlar (keySet)
for (String ulke : hm.keySet()) {
System.out.println("Key: " + ulke);
}
// Sadece Değerler (values)
for (String baskent : hm.values()) {
System.out.println("Value: " + baskent);
}
(Set)
(Collection)
Set<Map.Entry<K,V>> entrySet()
İkisini paket halinde verir.
Map.Entry Arayüzü Metotları
Hayati Önemli| Metot | Görev |
|---|---|
| getKey() | O anki satırın Anahtarını verir. |
| getValue() | O anki satırın Değerini verir. |
| setValue(yeniDeger) | Değeri değiştirir (Update). |
| equals(o) | Eşitlik kontrolü yapar. |
sort_by_alpha TreeMap Örneği
Otomatik Sıralar (Key'e göre)TreeMap ogrenci = new TreeMap<>();
// String ID olduğu için "Alfabetik" sıralar
ogrenci.put("20895229", "AKDENİZ YAĞMUR");
ogrenci.put("20793656", "AYKUL FATMA");
ogrenci.put("20794622", "ALP CEMRE");
// entrySet() ile döngü
for(Map.Entry me : ogrenci.entrySet()) {
// Veri Güncelleme (Update)
if(me.getValue().equals("ALP CEMRE")) {
me.setValue("ALP CEMRE (MEZUN)");
}
System.out.println(me.getKey() + " : " + me.getValue());
}
> 20793656 : AYKUL FATMA
> 20794622 : ALP CEMRE (MEZUN)
> 20895229 : AKDENİZ YAĞMUR
Pratik Örnekler & Çözümler
Constructor & Nesne Parametresi
assignment Görev
- Kitap Sınıfı:
advesayfadeğişkenleri olacak. - 2 Constructor: Biri sadece ad (sayfa=100), diğeri hem ad hem sayfa alacak.
- Bilgi Sınıfı: Parametre olarak
Kitapnesnesi alıp yazdıran metot olacak. - Test: 2 farklı nesne üretip yazdırılacak.
> Kitap Adi: Kitap 2, Sayfa sayisi: 150
class Kitap {
String ad;
int sayfa;
// Tek parametreli (Sayfa varsayılan 100)
public Kitap(String x) {
ad = x;
sayfa = 100;
}
// Çift parametreli
public Kitap(String x, int y) {
ad = x;
sayfa = y;
}
}
class Bilgi {
// Parametre olarak NESNE alıyor
void yazdir(Kitap kitap) {
System.out.println("Kitap: " + kitap.ad + " (" + kitap.sayfa + " syf)");
}
}
public class Soru1 {
public static void main(String[] args) {
Kitap k1 = new Kitap("Sefiller");
Kitap k2 = new Kitap("Nutuk", 500);
Bilgi b = new Bilgi();
b.yazdir(k1);
b.yazdir(k2);
}
}
Sayaç Sınıfı (Constructor Logic)
assignment Görev
- Sayaç Sınıfı:
deger(int) değişkeni olacak. - Constructor: Parametre negatifse değer 0 olacak, değilse atanacak.
- Metotlar:
artir()(değeri 1 artırır) vegetDeger(). - Test: -5 değeriyle nesne oluştur, 2 kez artır ve yazdır.
class Sayac {
int deger;
public Sayac(int x) {
if (x < 0) {
deger = 0; // Negatifse sıfırla
} else {
deger = x;
}
}
void artir() {
deger += 1;
}
int getDeger() {
return deger;
}
}
public class Soru2 {
public static void main(String[] args) {
Sayac s1 = new Sayac(-5); // Negatif girildi!
s1.artir();
s1.artir();
System.out.println("Deger: " + s1.getDeger());
}
}
Ürün Sınıfı & İndirim
assignment Görev
- Urun Sınıfı:
advefiyatözellikleri. - Constructor 1: Sadece ad alır, fiyatı 0 yapar.
- Constructor 2: Ad ve fiyat alır (Fiyat < 0 ise 0 yapar).
- Metot:
indirimYap(oran)fiyatı günceller. - Test: İki ürün oluştur, birine indirim yap ve yazdır.
> Ekmek : 12.0
class Urun {
String ad;
double fiyat;
// Sadece İsim
public Urun(String x) {
ad = x;
fiyat = 0;
}
// İsim + Fiyat
public Urun(String x, double y) {
ad = x;
fiyat = y;
}
void indirimYap(double oran) {
fiyat = fiyat * (100 - oran) / 100;
}
}
public class Soru3 {
public static void main(String[] args) {
Urun u1 = new Urun("Kalem");
Urun u2 = new Urun("Ekmek", 15);
u2.indirimYap(20); // %20 İndirim
System.out.println(u1.ad + " : " + u1.fiyat);
System.out.println(u2.ad + " : " + u2.fiyat);
}
}
Depo ve Kutu (Constructor Chaining)
assignment Görev
- Kutu Sınıfı: en, boy, yükseklik.
- Hacim Sınıfı: Parametre olarak Kutu alır ve hacmi hesaplar.
- 3 Constructor:
- 1. E, B, Y girilirse hepsi atanır.
- 2. Sadece E, B girilirse Y=10 olur.
- 3. Sadece Y girilirse E=10, B=10 olur.
- Main: Eksik verilere göre doğru constructor'ı seçer.
> Boy gir: 4
> Yükseklik gir: (Boş)
> Hacim: 200 (5 * 4 * 10)
class Kutu {
int en, boy, yukseklik;
// 1. Üçü de girilirse
public Kutu(int e, int b, int y) {
en = e; boy = b; yukseklik = y;
}
// 2. Yükseklik yoksa (Varsayılan 10)
public Kutu(int e, int b) {
en = e; boy = b; yukseklik = 10;
}
// 3. Sadece yükseklik varsa (En, Boy 10)
public Kutu(int y) {
en = 10; boy = 10; yukseklik = y;
}
}
class Hacim {
int hesapla(Kutu k) {
return k.en * k.boy * k.yukseklik;
}
}
Hacim Hesaplama & Math Sınıfı
function Görev
- Top Sınıfı:
renkveyaricapözellikleri. - Metot: Küre hacmini hesaplayan
hacimHesapla(). - Formül:
(4/3) * π * r³ - İpucu:
Math.PIveMath.pow()kullanılacak.
class Top {
String renk;
double yaricap;
public Top(String r, double y) {
renk = r;
yaricap = y;
}
public double hacimHesapla() {
// Formül: (4/3) * pi * r^3
return (4.0/3.0) * Math.PI * Math.pow(yaricap, 3);
}
}
public class Main {
public static void main(String[] args) {
Top t1 = new Top("Kirmizi", 3.0);
System.out.printf("%s Top Hacim: %.2f br³",
t1.renk,
t1.hacimHesapla()
);
}
}
function Görev
- Top Sınıfı:
renkveyaricapözellikleri. - Metot: Küre hacmini hesaplayan
hacimHesapla(). - Formül:
(4/3) * π * r³ - İpucu:
Math.PIveMath.pow()kullanılacak.
ArrayList: Araya Ekleme & Silme
edit_note Görev
- Bir
ArrayListoluştur ve 4 isim ekle (Ahmet, Ali, Bade, Ceyda). - Araya Ekle: 1. indekse "Vedat" ekle (Diğerleri kaymalı).
- Silme: "Ali" ismini ve 0. indeksteki ismi sil.
- Listeyi ve boyutunu (size) her adımda yazdır.
> "Vedat" eklendi (Index 1)
> Liste: [Ahmet, Vedat, Ali, Bade, Ceyda]
> Silinenler Sonrası (Ali & Index 0)
> Sonuç: [Vedat, Bade, Ceyda]
import java.util.ArrayList;
public class Main {
public static void main(String[] args) {
ArrayList isimler = new ArrayList<>();
// Ekleme
isimler.add("Ahmet");
isimler.add("Ali");
isimler.add("Bade");
isimler.add("Ceyda");
// Araya Ekleme (Kaydırma Yapar)
isimler.add(1, "Vedat");
System.out.println("Ekleme Sonrası: " + isimler);
// Silme İşlemleri
isimler.remove("Ali"); // İsme göre sil
isimler.remove(0); // İndekse göre sil (Ahmet gider)
// Sonuç
System.out.println("Son Durum: " + isimler);
System.out.println("Boyut: " + isimler.size());
// Tek Tek Yazdırma
for(int i=0; i < isimler.size(); i++) {
System.out.println("Index " + i + ": " + isimler.get(i));
}
}
}
HashMap: Nesne Saklama (Object Value)
person_add Senaryo
Map'ler sadece String/Integer tutmaz. Kendi yazdığımız sınıfları da tutabilir!
Ogrenciisminde bir sınıf oluştur (Ad, Soyad, Yaş).HashMap<String, Ogrenci>tanımla (Anahtar: No, Değer: Öğrenci).- 3 öğrenci nesnesi oluştur ve map'e ekle.
- Numara ile öğrencileri çekip bilgilerini yazdır.
> 21050555 -> Ali Yılmaz (19)
> 21050560 -> Veli Demir (20)
> 21050565 -> Ayşe Kaya (21)
import java.util.HashMap;
// Kendi Veri Tipimiz
class Ogrenci {
String ad, soyad;
int yas;
public Ogrenci(String ad, String soyad, int yas) {
this.ad = ad; this.soyad = soyad; this.yas = yas;
}
}
public class OkulSistemi {
public static void main(String[] args) {
// Key: String (No), Value: Ogrenci (Nesne)
HashMap sinif = new HashMap<>();
// Öğrencileri Ekle
sinif.put("21050555", new Ogrenci("Ali", "Yılmaz", 19));
sinif.put("21050560", new Ogrenci("Veli", "Demir", 20));
// Map içinde gezme (keySet ile)
for(String no : sinif.keySet()) {
Ogrenci ogr = sinif.get(no); // Nesneyi al
System.out.println(no + " -> " +
ogr.ad + " " + ogr.soyad + " (" + ogr.yas + ")");
}
}
}