Eğitim Portalı/Java/String İşlemleri ve StringBuilder
Java01-java/06-string-ve-metin

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 önemsizse equalsIgnoreCase() 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ılabilir
Ornek1.java
1// 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}
Çıktı yerel JDK 21 ile yakalandı — tarayıcıda JVM çalışmaz.

Ornek2

çalıştırılabilir
Ornek2.java
1// 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}
Çıktı yerel JDK 21 ile yakalandı — tarayıcıda JVM çalışmaz.

Ornek3

çalıştırılabilir
Ornek3.java
1// 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}
Çıktı yerel JDK 21 ile yakalandı — tarayıcıda JVM çalışmaz.