String İşlemleri ve StringBuilder
Metinlerle çalışmak, neredeyse her programın bir parçasıdır: kullanıcı adları, dosya içerikleri, mesajlar... Java'da metin denince akla String gelir. Bu bölümde String'in nasıl çalıştığını, en sık kullanılan metotları…
String İşlemleri ve StringBuilder
Metinlerle çalışmak, neredeyse her programın bir parçasıdır: kullanıcı adları, dosya
içerikleri, mesajlar... Java'da metin denince akla String gelir. Bu bölümde String'in
nasıl çalıştığını, en sık kullanılan metotlarını ve çok sayıda birleştirme gerektiğinde
neden StringBuilder'a geçmen gerektiğini öğreneceğiz.
String ve değişmezlik (immutability)
String'in en kritik özelliği değişmez (immutable) olmasıdır: bir String nesnesi bir
kez oluşturulduktan sonra içeriği asla değişmez. toUpperCase(), replace(), trim() gibi
metotlar orijinali değiştirmez; yeni bir String döndürür:
String s = "merhaba"; s.toUpperCase(); // sonucu kullanmazsan boşa gider! String b = s.toUpperCase(); // doğrusu: dönen değeri al
Bu davranış güvenlik ve performans (string havuzu) için faydalıdır ama bir tuzağı vardır: döngü içinde sürekli birleştirme yaparsan her adımda yeni nesne yaratılır.
Sık kullanılan metotlar
length, charAt, substring, indexOf, contains, startsWith, replace,
toUpperCase/toLowerCase, trim/strip ve split günlük hayatta en çok kullandıkların
arasındadır. split bir metni verilen ayraca göre parçalara bölüp dizi döndürür:
"elma,armut,kiraz".split(","); // ["elma", "armut", "kiraz"]
Örnek 1 (./Ornek1.java) bu metotları tek tek çalıştırır.
equals vs ==
Bu, yeni başlayanların en sık yaptığı hatadır. == iki referansın aynı nesne olup
olmadığına bakar; metinlerin içeriğini karşılaştırmak için equals() kullanılır:
String a = "merhaba"; String c = new String("merhaba"); a == c; // false (farklı nesneler) a.equals(c); // true (aynı içerik)
Kural: String'leri her zaman
equals()ile karşılaştır. Büyük/küçük harf önemsizseequalsIgnoreCase()kullan.
StringBuilder
String değişmez olduğundan, bir metni adım adım kurarken (özellikle döngüde) String +=
kullanmak yavaştır: her + yeni bir nesne üretir. StringBuilder değiştirilebilir bir
tampon sunar; append, insert, reverse, delete gibi metotlarla aynı nesneyi büyütür:
StringBuilder sb = new StringBuilder(); for (int i = 0; i < 1000; i++) sb.append(i); String sonuc = sb.toString();
Örnek 2 (./Ornek2.java) StringBuilder metotlarını gösterir ve aynı işi String += ile
StringBuilder ile yaparak süre farkını ölçer — aradaki uçurumu kendi gözünle göreceksin.
Birkaç parçayı birleştiriyorsan
+gayet iyidir; derleyici onu zaten optimize eder. Fark, döngüde çok sayıda birleştirmede ortaya çıkar.
Biçimlendirme ve text block
Düzenli çıktı için String.format(...) (veya printf) kullanılır; biçim belirteçleri
%d, %s, %.2f gibidir. Çok satırlı metinler için Java 15+ ile gelen text block
okunabilirliği artırır:
String json = """ { "ad": "Ada", "yas": 30 } """;
Pratik: küçük bir metin aracı
Örnek 3 (./Ornek3.java) öğrendiklerini birleştirir: bir cümledeki kelimeleri sayar,
kelime sırasını ters çevirir ve bir metnin palindrom olup olmadığını kontrol eder. split,
charAt, replaceAll ve StringBuilder'ı bir arada kullanır.
Özet
String'in değişmez olduğunu ve bunun sonuçlarını, en sık metotları, equals/== farkını
ve döngüde StringBuilder kullanmanın önemini gördük. Metin artık senin için bir araç
kutusu. Sırada, programların kaçınılmaz gerçeğiyle baş etmeyi öğreniyoruz: hatalar ve
istisnalar.
▶ Kod Örnekleri(3)
Ornek1
çalıştırılabilir1// Ornek1: String API turu ve equals vs == farkı.
2// Çalıştırma: java Ornek1.java
3public class Ornek1 {
4
5 public static void main(String[] args) {
6 String s = " Java Programlama Dili ";
7 System.out.println("Orijinal: [" + s + "]");
8
9 // Sık kullanılan String metotları (String IMMUTABLE'dır:
10 // her metot YENİ bir String döndürür, orijinali değişmez).
11 System.out.println("length() : " + s.length());
12 System.out.println("trim() : [" + s.trim() + "]");
13 System.out.println("toUpperCase() : " + s.trim().toUpperCase());
14 System.out.println("toLowerCase() : " + s.trim().toLowerCase());
15 System.out.println("substring(2,6): " + s.trim().substring(0, 4));
16 System.out.println("indexOf('Dili'): " + s.indexOf("Dili"));
17 System.out.println("contains('Prog'): " + s.contains("Prog"));
18 System.out.println("replace : " + s.trim().replace("Dili", "Eğitimi"));
19 System.out.println("startsWith(' '): " + s.startsWith(" "));
20
21 // split: metni parçalara böler, dizi döndürür.
22 String csv = "elma,armut,kiraz";
23 String[] meyveler = csv.split(",");
24 System.out.println("\nsplit ile " + meyveler.length + " parça:");
25 for (String m : meyveler) System.out.println(" - " + m);
26
27 // --- equals vs == ---
28 // == referansları (aynı nesne mi?), equals() içeriği (aynı metin mi?) karşılaştırır.
29 String a = "merhaba";
30 String b = "merhaba"; // literal havuzundan aynı nesne
31 String c = new String("merhaba"); // new ile FARKLI nesne
32
33 System.out.println("\n--- equals vs == ---");
34 System.out.println("a == b : " + (a == b)); // genelde true (string pool)
35 System.out.println("a == c : " + (a == c)); // false: farklı nesne
36 System.out.println("a.equals(c) : " + a.equals(c)); // true: aynı içerik
37 // KURAL: String'leri her zaman equals() ile karşılaştır.
38 }
39}Ornek2
çalıştırılabilir1// Ornek2: StringBuilder ve performans karşılaştırması.
2// Çalıştırma: java Ornek2.java
3public class Ornek2 {
4
5 public static void main(String[] args) {
6 // StringBuilder DEĞİŞTİRİLEBİLİR bir metin tamponudur.
7 StringBuilder sb = new StringBuilder();
8 sb.append("Java");
9 sb.append(" ").append("çok").append(" güçlü");
10 sb.insert(0, ">> "); // başa ekle
11 System.out.println("append/insert: " + sb);
12 System.out.println("reverse() : " + new StringBuilder("tacik").reverse());
13 System.out.println("uzunluk : " + sb.length());
14
15 // --- Performans: döngüde String birleştirme vs StringBuilder ---
16 // String IMMUTABLE olduğu için her + işlemi YENİ bir nesne yaratır; bu, çok
17 // sayıda birleştirmede yavaştır. StringBuilder tek tampon kullanır.
18 int tekrar = 50_000;
19
20 long t1 = System.nanoTime();
21 String duz = "";
22 for (int i = 0; i < tekrar; i++) {
23 duz += i; // her adımda yeni String -> yavaş
24 }
25 long t2 = System.nanoTime();
26
27 StringBuilder hizli = new StringBuilder();
28 for (int i = 0; i < tekrar; i++) {
29 hizli.append(i); // aynı tamponu büyütür -> hızlı
30 }
31 long t3 = System.nanoTime();
32
33 System.out.println("\n" + tekrar + " birleştirme için süre:");
34 System.out.printf(" String += : %5d ms%n", (t2 - t1) / 1_000_000);
35 System.out.printf(" StringBuilder : %5d ms%n", (t3 - t2) / 1_000_000);
36 System.out.println("Sonuç uzunlukları eşit mi? " + (duz.length() == hizli.length()));
37 System.out.println("\nKural: döngüde çok sayıda birleştirme yapıyorsan StringBuilder kullan.");
38 }
39}Ornek3
çalıştırılabilir1// Ornek3: Metin işleme mini uygulaması — kelime sayma, ters çevirme, palindrom.
2// Çalıştırma: java Ornek3.java
3public class Ornek3 {
4
5 // Bir cümledeki kelime sayısını döndürür.
6 static int kelimeSay(String cumle) {
7 String temiz = cumle.trim();
8 if (temiz.isEmpty()) return 0;
9 return temiz.split("\\s+").length; // bir veya çok boşluğa göre böl
10 }
11
12 // Kelimelerin sırasını ters çevirir.
13 static String kelimeleriTersCevir(String cumle) {
14 String[] kelimeler = cumle.trim().split("\\s+");
15 StringBuilder sb = new StringBuilder();
16 for (int i = kelimeler.length - 1; i >= 0; i--) {
17 sb.append(kelimeler[i]);
18 if (i > 0) sb.append(" ");
19 }
20 return sb.toString();
21 }
22
23 // Palindrom mu? (boşluk ve büyük/küçük harf yok sayılır)
24 static boolean palindromMu(String metin) {
25 String s = metin.toLowerCase().replaceAll("[^a-zçğıöşü0-9]", "");
26 int sol = 0, sag = s.length() - 1;
27 while (sol < sag) {
28 if (s.charAt(sol) != s.charAt(sag)) return false;
29 sol++;
30 sag--;
31 }
32 return true;
33 }
34
35 public static void main(String[] args) {
36 String cumle = "Java ile metin islemek kolaydir";
37 System.out.println("Cümle: \"" + cumle + "\"");
38 System.out.println("Kelime sayısı : " + kelimeSay(cumle));
39 System.out.println("Ters sıra : " + kelimeleriTersCevir(cumle));
40
41 System.out.println("\nPalindrom testleri:");
42 for (String kelime : new String[]{"kayak", "ey edip adanada pide ye", "merhaba"}) {
43 System.out.printf(" %-28s -> %s%n", "\"" + kelime + "\"",
44 palindromMu(kelime) ? "palindrom" : "değil");
45 }
46 }
47}