İçeriğe geç

String — Hiç Değişmeyen Metin

Başlangıç 8 dk Çok sık karşılaşılır

Önce şunu oku: Stack, Heap ve Pass-by-Value

30 saniyede özet

Bir String oluşturulduktan sonra hiç değişmez; her 'değişiklik' yeni bir String üretir. Metinleri equals ile karşılaştırırsın, döngüde metin biriktirirken de StringBuilder kullanırsın.

Bir arkadaşına not yazdın, sonra bir kelimeyi düzeltmek istedin. Kâğıt mürekkeple yazıldığı için silemiyorsun; yeni bir kâğıda baştan yazıyorsun.

Java’da metinler de böyle çalışır ve bu küçük bilgi birçok şaşkınlığı tek seferde çözer.

String hiç değişmez: her 'değişiklik' yeni bir kutu açar.
Adım adım oku
  1. s değişkeni, içinde merhaba yazan bir kutuyu gösteriyor.
  2. toUpperCase() çağrılınca yeni bir kutu açılır: MERHABA. Eski kutu olduğu gibi durur.
  3. s'nin oku ancak sonucu s'ye atayınca yeni kutuya taşınır.
  4. Eski kutunun içi hiç değişmedi; sadece artık onu gösteren yok.
  1. Bayt: isim.toUpperCase() yazdım ama isim hâlâ küçük harf!

  2. Sen: Metot bozuk mu?

  3. Bayt: Hayır, çalıştı. Yeni bir metin üretti ve sen onu bir yere koymadın.

  4. Bayt: String'in tek kuralı bu: hiç değişmez. Gel, neden işe yaradığına bakalım.

String hiç değişmez

Bir String bir kez oluşturulduktan sonra içi hiç değişmez. Böyle nesnelere immutableOluşturulduktan sonra içi değişmeyen nesne. Anahtar olarak güvenlidir, çünkü hashCode'u hiç değişmez.Sözlükte gör → denir.

toUpperCase, trim, replace gibi metotlar eski metni değiştirmez. Yeni bir String döndürür.

Sonucu bir yere koy
String isim = "ayşe";
isim.toUpperCase(); // yeni metin üretildi ve kayboldu
System.out.println(isim); // ayşe
isim = isim.toUpperCase(); // ok yeni metne taşındı
System.out.println(isim); // AYŞE

Bu kural bir kısıtlama gibi görünür ama çok işe yarar. Değişmeyen bir metni herkes güvenle paylaşabilir: HashMap anahtarı olabilir, birden çok thread aynı anda okuyabilir.

Kafam karıştı, daha basit anlat

String’i mürekkeple yazılmış bir not gibi düşün. Düzeltmek istediğinde yeni bir not yazılır. Yeni notu tutmak istiyorsan onu bir değişkene koymalısın.

Hızlı kontrolBaşlangıç

Program ne yazdırır?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.
Isim.java
1String isim = " ayşe ";
2isim.trim();
3isim.toUpperCase();
4System.out.println("[" + isim + "]");
Java 21UTF-8LF

== mi, equals mı?

Kullanıcı klavyeden elma yazdı ve bu metin girdi değişkenine geldi. `girdi == "elma"` ne döner? Cevabı göster

Büyük ihtimalle false. Klavyeden gelen metin program çalışırken yeni bir nesne olarak üretilir. == harflere değil, iki değişkenin aynı nesneyi gösterip göstermediğine bakar.

== iki değişkenin aynı kutuyu gösterip göstermediğini sorar. equals ise kutuların içindeki harflerin aynı olup olmadığını sorar.

Java, koda doğrudan yazdığın metinleri string poolKoda doğrudan yazılan metinlerin tek kopya olarak tutulduğu ortak raf. Aynı sabit metni kullanan her yer aynı nesneyi paylaşır.Program çalışırken üretilen metinler (klavyeden, ağdan, birleştirmeden) bu rafa kendiliğinden girmez. Bu yüzden == bazen tesadüfen true verir; metinler her zaman equals ile karşılaştırılır.Sözlükte gör → denen ortak bir rafta tutar. Bu yüzden iki aynı sabit metin bazen aynı kutu olur ve == şans eseri doğru çıkar.

Metinleri hep equals ile karşılaştır
String a = "elma";
String b = new String("elma");
a == b; // false: iki ayrı kutu
a.equals(b); // true: harfler aynı
Kafam karıştı, daha basit anlat

İki kişinin aynı kitabı okuması ile aynı nüsha üzerinden okuması farklı şeylerdir. equals kitabın aynı olup olmadığını, == ise elindeki nüshanın aynı olup olmadığını sorar.

Hızlı kontrolBaşlangıç

İki metnin aynı harflerden oluşup oluşmadığını nasıl kontrol edersin?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Program ne yazdırır?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.
Karsilastir.java
1String a = "elma";
2String b = "elma";
3String c = new String("elma");
4System.out.println((a == b) + " " + (a == c) + " " + a.equals(c));
Java 21UTF-8LF

Satır satır: döngüde metin biriktirmek

Metin değişmediğine göre, bir döngüde her += ne yapar? Kısa bir iz sürelim.

Her += yeni bir metin demek

Rapor.java
şu an çalışan satırString rapor = "";
2for (String satir : satirlar) {
3 rapor += satir + "\n";
4}
5System.out.println(rapor);

Debug

Adım 1/5

başlangıç Boş bir metinle başlıyoruz.

rapor
= ""
üretilen metin
= 1
Java 21UTF-8LF1:1

Sol/sağ ok tuşlarıyla da gezebilirsin.

Döngüde metin biriktirmek

Tohum 57855

Oynat ya da adımla: her adım döngünün beşte birini işler.

Hız
Adım 0

Şu an ne oldu?

1.000 satırlık rapor

Aynı rapor iki yolla biriktiriliyor; kaç karakter yazıldığını sayıyoruz.

Görevler0/2

  • += ile StringBuilder’dan 100 kat fazla karakter yazdıraçık

    İpucu

    Uzun bir rapor.

  • Farkın 5 katın altında kaldığı bir rapor bulaçık

    İpucu

    Kısa listelerde fark küçüktür.

Olay günlüğü (0)

Henüz olay yok. Oynat veya adımla.

  1. Varsayılanla oynat. 1.000 satırda += yaklaşık 20 milyon karakter yazdı, StringBuilder 85 bin.
  2. “100 satır” seç. Fark yaklaşık 22 kat.
  3. “10 satır” seç. Fark iki kat kadar: kısa listede okunabilirlik öncelikli olabilir.
Hızlı kontrolBaşlangıç

Bir döngüde binlerce satırı `rapor += satir` ile birleştirmek neden yavaşlar?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

StringBuilder ne zaman gerekir?

StringBuilder değişebilen bir metin defteridir. append ile sona ekler, en sonda toString() ile tek bir String üretirsin.

Döngüde StringBuilder
StringBuilder rapor = new StringBuilder();
for (String satir : satirlar) {
rapor.append(satir).append('\n');
}
String sonuc = rapor.toString();

Tek satırlık birleştirmelerde ("Merhaba " + isim) buna gerek yok. Derleyici o satırı zaten verimli hâle getirir; sorun yalnızca döngüde birikmedir.

Kafam karıştı, daha basit anlat

Tek bir cümle kuruyorsan + yeter. Yüzlerce satırlık bir liste topluyorsan defteri aç: StringBuilder.

Hızlı kontrolBaşlangıç

Hangi durumda StringBuilder kullanmak gerçekten fark yaratır?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Bankada da hesap ekstresi tam böyle kurulur: satırlar döngüde bir deftere eklenir, en sonda tek bir metin olarak basılır.

Derinleş · Hesap ekstresi: satırları biriktirmek 3 dosya · ~31 satır · ilk okumada atlayabilirsin
Proje dosyaları

src/main/java/com/bank/statement/ Movement.java Bir hareket: tarih, açıklama ve tutar. Değişmez bir record.

src/main/java/com/bank/statement/Movement.java
public record Movement(LocalDate date, String description, BigDecimal amount) {
}

src/main/java/com/bank/statement/ StatementPrinter.java Ekstre metni: satırlar tek bir StringBuilder'a eklenir, en sonda bir kez String'e çevrilir.

src/main/java/com/bank/statement/StatementPrinter.java
public final class StatementPrinter {
public String print(String iban, List<Movement> movements) {
StringBuilder text = new StringBuilder();
text.append("Hesap: ").append(iban).append('\n');
for (Movement movement : movements) {
text.append(movement.date())
.append(" ")
.append(movement.description())
.append(" ")
.append(movement.amount())
.append('\n');
}
return text.toString();
}
}

src/main/java/com/bank/statement/ Main.java Çıktı yorumlarda.

src/main/java/com/bank/statement/Main.java
public class Main {
public static void main(String[] args) {
List<Movement> movements = List.of(
new Movement(LocalDate.of(2026, 9, 1), "Maaş", new BigDecimal("42000.00")),
new Movement(LocalDate.of(2026, 9, 3), "Market", new BigDecimal("-850.40")));
System.out.print(new StatementPrinter().print("TR00 0001 0000 0000 0000 0000 01", movements));
// Hesap: TR00 0001 0000 0000 0000 0000 01
// 2026-09-01 Maaş 42000.00
// 2026-09-03 Market -850.40
}
}

Tuzaklar

Sonucu atamamak. isim.trim(); tek başına hiçbir şey yapmaz. Sonucu bir değişkene koy.

Metinleri == ile karşılaştırmak. Testte çalışıp gerçek girdide bozulabilir. Metin karşılaştırmasında hep equals kullan.

Noktayla bölmek. split bir kalıp (regex) bekler ve orada nokta “herhangi bir karakter” demektir. "a.b".split(".") boş bir dizi döner; doğrusu split("\\.").

Hızlı kontrolBaşlangıç

Bu kod kullanıcı 'evet' yazsa bile çoğu zaman "İptal edildi" diyor. Hatalı satır hangisi?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.

Hatalı satıra dokun, sonra kontrol et.

Onay.java
Java 21UTF-8LF

Kendini sına

Şimşek turu1/4

`isim.toUpperCase()` çağrısı isim değişkenini büyük harfe çevirir.

Soru 1/3Başlangıç

Program ne yazdırır?

Cevabı biliyor musun?Önce birini seç. Tekrar zamanlaması buna göre ayarlanıyor.
Bol.java
1String surum = "21.0.4";
2System.out.println(surum.split(".").length + " " + surum.split("\\.").length);
Java 21UTF-8LF

Aklında kalacak üç şey

  1. 1 String değişmez. toUpperCase gibi metotlar yeni bir String döndürür, sonucu bir değişkene atamazsan kaybolur.
  2. 2 İki metnin aynı olup olmadığını equals söyler. == yalnızca aynı nesne olup olmadıklarına bakar.
  3. 3 Döngü içinde metin biriktirirken StringBuilder kullanılır; tek satırlık birleştirmelerde düz + yeterlidir.
Sonraki kapı Bir listeyi final yaptın ama içine eleman eklemeye devam edebiliyorsun. final ne işe yarıyor? final ve static — Kilitli Olan ve Ortak Olan · 8 dk

3 kart sonraki derste seni bekliyor

0/4 kart bu dersten toplandı

Bu dersin üstüne kurulanlar

Bunlar bu dersi temel alıyor; hazır olduğunda devam edebilirsin.