Bölüm 3.4: Dizgiler
Giriş
Öğrenme Çıktıları
String nesnesini dizgi sabitiyle (literal) ve new ile oluşturmak; + birleştirmesinin sırasını açıklamak.
charAt, length, indexOf, substring ile parçalara erişmek; dizgide döngüyle gezinmek.
Metotların yeni nesne döndürdüğünü bellekte göstermek; döngüde StringBuilder kullanmak.
next(), nextLine(), nextInt() farkını açıklamak; satır sonu tuzağından kaçınmak.
== ile equals() farkını dizgi havuzuyla açıklamak; compareTo ve benzerlerini kullanmak.
printf ve String.format ile genişlik, hizalama ve hassasiyeti ayarlamak.
Dizgi Kavramı
Dizgi (String) Nedir?
- Dizgi (string), karakterlerden oluşan bir metni saklayan bir nesnedir; tipi
java.lang.Stringsınıfıdır. Stringbir sınıftır, ilkel tip değildir; adı büyük harfle başlar.importgerekmez.- Çift tırnak içindeki
"Tarkan"gibi sabitler dizgi sabitidir (string literal); nesnenewkullanılmadan oluşur. - Karakterler Unicode ile saklanır:
ç ğ ı İ ö ş ügibi Türkçe harfler sorunsuzdur. - Tek karakter
charile tek tırnakta ('T'), metinStringile çift tırnakta ("T") yazılır.
String ad = "Tarkan";
String adSoyad = "Mustafa Sandal";
String nokta = "(" + 3 + ", " + 5 + ")";
System.out.println(ad);
System.out.println(adSoyad);
System.out.println(nokta);Tarkan Mustafa Sandal (3, 5)
Dizgi, sıralı karakter kutuları gibidir.
Dizgi Kavramı
Dizgi Oluşturma ve Birleştirme (+)
String s0 = "Giresun"; // deyim char[] harfler = {'J', 'a', 'v', 'a'}; String s1 = new String(harfler); // char[] String s2 = String.valueOf(42); // sayıdan String s3 = "Giresun".concat(" Üni."); System.out.println(s1 + " " + s2 + " " + s3); System.out.println("Toplam: " + 3 + 5); System.out.println("Toplam: " + (3 + 5)); System.out.println(3 + 5 + " elma"); System.out.println('a' + 'b' + "c"); System.out.println("" + 'a' + 'b');
Java 42 Giresun Üni. Toplam: 35 Toplam: 8 8 elma 195c ab
+işlecinin bir yanıStringise diğer yan da dizgiye çevrilir ve birleştirilir (concatenation).+soldan sağa işlenir:"Toplam: " + 3önce"Toplam: 3"olur, sonra5eklenir →Toplam: 35.- Toplam parantezle elde edilir:
"Toplam: " + (3 + 5). 3 + 5 + " elma": önce sayılar toplanır (8), sonra dizgi eklenir.'a' + 'b'ikichar'ın sayısal toplamıdır (97 + 98 = 195). Başa""koymak dizgi birleştirmeyi zorlar.- Her birleştirme yeni bir
Stringnesnesi üretir.
Dizgi Kavramı · Adım adım kod izleme
+ Soldan Sağa: Toplama mı, Birleştirme mi?
İki int değişken. Her satırda + soldan sağa işlenir; her adımda tip kontrol edilir.
Sol yan String: 4 dizgiye çevrilip eklenir → "Sonuç: 4".
Sonuç hâlâ String; 2 de metin olarak eklenir → "Sonuç: 42", toplam değil!
Parantez önce: 4 + 2 iki int, sayısal toplam 6.
Sonra dizgiyle birleşir → "Sonuç: 6".
Soldaki iki yan da int: önce toplanır → 6.
6 + " kalem": artık String → "6 kalem".
'x' + 'y': iki char sayı gibi toplanır: 120 + 121 = 241.
241 + "z" → "241z".
Başta boş dizgi: "" + 'x' String olur → "x".
"x" + 'y' → "xy": char metin olarak eklendi.
İlk satır yazılır.
İkinci satır yazılır. Kural: bir yan String olduğu anda birleştirme; o ana kadar sayılar toplanır.
int a = 4, b = 2;
String s1 = "Sonuç: " + a + b;
String s2 = "Sonuç: " + (a + b);
String s3 = a + b + " kalem";
String s4 = 'x' + 'y' + "z";
String s5 = "" + 'x' + 'y';
System.out.println(s1 + " | " + s2);
System.out.println(s3 + " | " + s4 + " | " + s5);Dizgi Kavramı
İndisleme (Indexing)
- İlk karakterin indisi 0, sonuncunun
length() - 1. charAt(i):iindisli karakter (char).length()bir metottur, parantez gerekir (dizilerdekilengthise alandır).- Uzunluğu aşan ya da negatif indis: çalışma zamanında
StringIndexOutOfBoundsException. charbir sayıdır (Unicode kodu):c + 1sayı,(char) (c + 1)sonraki harf.
String isim = "Tarkan"; System.out.println(isim.length()); System.out.println(isim.charAt(0)); System.out.println(isim.charAt(isim.length() - 1)); char c = isim.charAt(2); System.out.println(c + 1); System.out.println((char) (c + 1));
6 T n 115 s
String s = "Java"; System.out.println(s.charAt(4));
Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
Index 4 out of bounds for length 4Dizgi Kavramı · Adım adım kod izleme
Karakterlerde Gezinmek: Adım Adım
Ekrana istem yazılır; print alt satıra geçmez.
Kullanıcı Giresun yazıp Enter'a basar; nextLine() satırın tamamını okur.
i = 0: charAt(0) = 'G'; satır yazdırılır, sonra i += 2.
i = 2: charAt(2) = 'r'; satır yazdırılır, sonra i += 2.
i = 4: charAt(4) = 's'; satır yazdırılır, sonra i += 2.
i = 6: charAt(6) = 'n'; satır yazdırılır, sonra i += 2.
i = 8 için 8 < 7 yanlış: döngü biter. Son indis 6'dır, 7 kullanılmaz.
Scanner kapatılır, program sona erer.
Scanner scanner = new Scanner(System.in); System.out.print("Bir kelime giriniz: "); String kelime = scanner.nextLine(); for (int i = 0; i < kelime.length(); i += 2) { char harf = kelime.charAt(i); System.out.println((i + 1) + ". harf: " + harf); } scanner.close();
Dizgi Metotları
Temel Dizgi Metotları
| Metot | Ne yapar? | s = "Java Programlama" için |
|---|---|---|
length() | Karakter sayısını döndürür. | 16 |
charAt(i) | i indisli karakter (char). | s.charAt(0) → 'J' |
indexOf(str) | Alt dizginin ilk başlangıç indisi; bulunamazsa −1. | s.indexOf("Programlama") → 5s.indexOf("C++") → -1 |
indexOf(str, bas) | Aramaya bas indisinden başlar. | s.indexOf("a", 4) → 10 |
lastIndexOf(str) | Son geçtiği yerin indisi. | s.lastIndexOf('a') → 15 |
substring(i1, i2) | i1 dahil, i2 hariç arasındaki alt dizgi. | s.substring(5, 12) → "Program" |
substring(i1) | i1'den sona kadar. | s.substring(5) → "Programlama" |
toLowerCase() | Küçük harfli yeni dizgi. | "java programlama" |
toUpperCase() | Büyük harfli yeni dizgi. | "JAVA PROGRAMLAMA" |
Hiçbir metot s'yi değiştirmez; sonuç her zaman yeni bir değer olarak döner.
Dizgi Metotları · Adım adım kod izleme
indexOf ve substring: Adım Adım
16 karakterlik dizgi; boşluk da bir karakterdir (indis 4).
indexOf("Programlama") eşleşmenin başladığı indisi verir: 5.
length() = 16; indisler 0 … 15.
substring(5, 12): 5, 6, …, 11 → "Program" (12 − 5 = 7 karakter).
substring(5) → "Programlama".
toLowerCase() yeni bir dizgi döndürür; str hâlâ "Java Programlama".
toUpperCase() da yeni dizgi döndürür. Orijinal dizgi hiç değişmedi.
String str = "Java Programlama"; int indeks = str.indexOf("Programlama"); int uzunluk = str.length(); String alt = str.substring(5, 12); String son = str.substring(5); String kucuk = str.toLowerCase(); String buyuk = str.toUpperCase();
Dizgi Metotları
Diğer Yararlı Metotlar
String s = " Merhaba Dünya ";
System.out.println("[" + s.trim() + "]");
System.out.println("[" + s.replace('a', 'e') + "]");
String[] meyveler = "elma,armut,kiraz".split(",");
System.out.println(meyveler.length);
System.out.println(meyveler[1]);
System.out.println(String.join(" - ", meyveler));
System.out.println("ab".repeat(3)); // Java 11+
System.out.println("".isEmpty());
System.out.println(" ".isBlank()); // Java 11+
char[] dizi = "Java".toCharArray();
System.out.println(dizi.length + " " + dizi[0]);
System.out.println("Giresun".replace("sun", "SUN"));
System.out.println(String.valueOf(3.5) + 1);
System.out.println(Integer.parseInt("42") + 1);[Merhaba Dünya] [ Merhebe Dünye ] 3 armut elma - armut - kiraz ababab true true 4 J GireSUN 3.51 43
trim(): baştaki/sondaki boşlukları atar.replace: tüm eşleşmeleri değiştirir.split(ayrac): parçalarıString[]dizisi olarak verir;String.jointersini yapar.String.valueOf(x): sayı → dizgi;Integer.parseInt(s),Double.parseDouble(s): dizgi → sayı.
Değiştirilemezlik
Değiştirilemez (Immutable) Nesne
Stringnesneleri oluşturulduktan sonra değiştirilemez (immutable).toUpperCase,replace,substring,+orijinali değiştirmez; yeni bir nesne döndürür.- Sonucu kullanmak için atamak gerekir:
s = s.toUpperCase(); - Faydaları: güvenli ve tutarlı kod (dizgiyi paylaşan kodlar birbirini bozamaz), dizgi havuzu (string pooling) ile bellek tasarrufu, iş parçacıkları arasında güvenli paylaşım.
String s = "Giresun Üniversitesi"; s.toUpperCase(); // sonuç kaybolur System.out.println(s); s = s.toUpperCase(); // sonuç s'ye atanır System.out.println(s);
Giresun Üniversitesi GİRESUN ÜNİVERSİTESİ
Türkçe yerel ayarlı (tr-TR) bilgisayarda çıktı GİRESUN ÜNİVERSİTESİ, İngilizce ayarda GIRESUN ÜNIVERSITESI olur.
Değiştirilemezlik · Adım adım kod izleme
Değiştirilemezlik: Bellekte Adım Adım
Dizgi sabiti havuzda bir nesnedir; s onu gösterir.
toUpperCase() yeni bir nesne üretir. Ama sonuç hiçbir değişkene atanmadı!
s hâlâ eski nesneyi gösterir: orijinal metin yazılır. Sahipsiz nesne çöp toplayıcıya kalır.
Yine yeni bir nesne oluşur ve bu kez referansı s'ye atanır. Eski nesne değişmedi, yalnızca ok yer değiştirdi.
s artık büyük harfli nesneyi gösterir.
String s = "Giresun Üniversitesi"; s.toUpperCase(); System.out.println(s); s = s.toUpperCase(); System.out.println(s);
Değiştirilemezlik
Türkçe Harfler ve Yerel Ayar (Locale)
import java.util.Locale;
String s = "Giresun Üniversitesi";
System.out.println(s.toUpperCase());
System.out.println(s.toUpperCase(Locale.ROOT));
System.out.println("TITLE".toLowerCase());
System.out.println("TITLE".toLowerCase().equals("title"));
System.out.println("TITLE".toLowerCase(Locale.ROOT));GİRESUN ÜNİVERSİTESİ GIRESUN ÜNIVERSITESI tıtle false title
| Dönüşüm | Türkçe (tr) | ROOT / İngilizce |
|---|---|---|
i → büyük | İ | I |
I → küçük | ı | i |
ı → büyük | I | I |
- Parametresiz
toUpperCase()/toLowerCase()bilgisayarın varsayılan yerel ayarını kullanır: aynı program farklı makinede farklı sonuç verebilir. - Türkçe ayarda
"TITLE".toLowerCase()→"tıtle": karşılaştırmafalse! - Komut, dosya adı gibi metinlerde
Locale.ROOT; Türkçe metindeLocale.forLanguageTag("tr-TR")verilir.
Değiştirilemezlik
Döngüde Birleştirme ve StringBuilder
String sonuc = ""; for (int i = 1; i <= 5; i++) { sonuc += i + " "; // her turda yeni String } System.out.println(sonuc); StringBuilder sb = new StringBuilder(); for (int i = 1; i <= 5; i++) { sb.append(i).append(' '); // aynı nesne büyür } String metin = sb.toString(); System.out.println(metin); StringBuilder ters = new StringBuilder("Giresun"); ters.reverse(); System.out.println(ters); StringBuilder k = new StringBuilder("Java"); k.insert(0, ">> ").append('!'); k.setCharAt(3, 'j'); System.out.println(k + " " + k.length());
1 2 3 4 5 1 2 3 4 5 nuseriG >> java! 8
sonuc += ...her turda eski metni kopyalayıp yeni bir nesne oluşturur; n turda yaklaşık n²/2 karakter kopyalanır.StringBuilderdeğiştirilebilir (mutable) bir karakter tamponudur:append,insert,reverse,setCharAt,deleteCharAtaynı nesne üzerinde çalışır.- İş bitince
toString()ileString'e çevrilir. - Birkaç parçalık birleştirmede
+yeterli ve okunaklıdır; döngü içinde çok birleştirmedeStringBuildertercih edilir.
Değiştirilemezlik · Adım adım kod izleme
StringBuilder: Tek Tampon, Yerinde Değişiklik
Tek bir değiştirilebilir tampon: 4 karakter dolu, kapasite 16 + 4 = 20.
append(' '): boşluk sona eklenir; aynı nesne, yeni nesne yok.
Zincirdeki ikinci append(8): sayı karakter olarak eklenir. append nesnenin kendisini döndürdüğü için zincir kurulabilir.
insert(0, ">> "): baştaki 3 hücreye yer açmak için diğer karakterler sağa kayar.
setCharAt(3, 'j'): 3. indis yerinde değişti. String'de bu mümkün değildi.
deleteCharAt(7): sondaki '8' silindi, uzunluk 8.
16 karakter daha: 24 > 20, sığmaz. Tampon büyür: yeni kapasite (20 + 1) × 2 = 42, eski içerik kopyalanır.
toString(): tamponun o anki içeriğiyle yeni bir String oluşur.
Uzunluk 24, kapasite 42 yazılır.
StringBuilder sb = new StringBuilder("Java");
sb.append(' ').append(8);
sb.insert(0, ">> ");
sb.setCharAt(3, 'j');
sb.deleteCharAt(sb.length() - 1);
sb.append("programlama dili");
String s = sb.toString();
System.out.println(s + " " + sb.length() + " " + sb.capacity());Kullanıcı Girişi
Kullanıcı Girişi: Scanner
java.util.Scannersınıfı klavyeden (System.in) girdi okur:import java.util.Scanner;next(): boşlukları atlar, bir sonraki kelimeyi (boşluğa kadar) okur.nextLine(): bulunduğu yerden satır sonuna kadar her şeyi okur; satır sonu karakterini tüketir ama sonuca katmaz.nextInt(),nextDouble(): bir sayı okur; arkasındaki satır sonunu tamponda bırakır. Sayı yerine harf girilirseInputMismatchExceptionoluşur.- İş bitince
klavye.close().
Scanner klavye = new Scanner(System.in); System.out.println("bir metin giriniz"); String girdi = klavye.next(); System.out.println(girdi); // bilgisayar girdi = klavye.next(); System.out.println(girdi); // ve girdi = klavye.nextLine(); System.out.println(girdi); // programlamaya giriş
bilgisayar ve programlamaya giriş
bir metin giriniz bilgisayar ve programlamaya giriş
nextLine() sonucunun başında bir boşluk vardır: “ve” kelimesinden sonraki boşluk da satırın parçasıdır.
Kullanıcı Girişi · Adım adım kod izleme
next() ve nextLine(): Adım Adım
İstem yazılır; program kullanıcının satırı girmesini bekler.
Kullanıcı satırı yazıp Enter'a basar (tamponda ⏎ de vardır). next() ilk boşluğa kadar okur: "bilgisayar".
Okunan kelime yazdırılır. İmleç boşluğun önünde bekler.
next() önce boşluğu atlar, sonra "ve" kelimesini okur.
Yazdırılır. İmleç yine bir boşluğun önünde.
nextLine() boşluğu atlamaz: satır sonuna kadar okur, ⏎'yi tüketir: " programlamaya giriş".
Baştaki boşlukla birlikte yazdırılır. Tampon boşaldı.
Scanner klavye = new Scanner(System.in);
System.out.println("bir metin giriniz");
String girdi = klavye.next();
System.out.println(girdi);
girdi = klavye.next();
System.out.println(girdi);
girdi = klavye.nextLine();
System.out.println(girdi);Kullanıcı Girişi
nextInt() Sonrası nextLine() Tuzağı
Hatalı: ad hiç sorulmadan geçilir.
Scanner klavye = new Scanner(System.in); System.out.print("Yaş: "); int yas = klavye.nextInt(); System.out.print("Ad: "); String ad = klavye.nextLine(); System.out.println("[" + ad + "] " + yas);
Yaş: 19 Ad: [] 19
Doğru: artakalan satır sonunu tüket.
int yas = klavye.nextInt(); klavye.nextLine(); // ⏎'yi at System.out.print("Ad: "); String ad = klavye.nextLine();
Yaş: 19 Ad: Ayşe [Ayşe] 19
nextInt() yalnızca 19'u alır. Hemen ardından gelen nextLine(), ⏎'ye kadar olan boş metni okur. Alternatif: her şeyi nextLine() ile okuyup Integer.parseInt ile çevirmek.
Karşılaştırma
== ile Karşılaştırma
==işleci nesnelerin referanslarını (bellekteki adreslerini) karşılaştırır, içeriklerini değil.- İki değişken aynı nesneyi gösteriyorsa
true, içerik aynı olsa bile farklı nesneler isefalsedöner. str1 == str2'nintrueçıkması bir şans değil, dizgi havuzunun sonucudur.
== ile karşılaştırılamaz; içerik karşılaştırması equals() ile yapılır.String str1 = "Giresun"; String str2 = "Giresun"; String str3 = new String("Giresun"); System.out.println(str1 == str2); // true System.out.println(str1 == "Giresun"); // true System.out.println(str1 == str3); // false System.out.println(str3 == "Giresun"); // false
true true false false
Karşılaştırma
Dizgi Havuzu (String Pool)
- Kaynak koddaki
"giresun"gibi sabit ifadeler dizgi sabitleridir (literal). - Dizgi sabitleri heap'teki özel bir bölgede, dizgi havuzunda saklanır: içeriği aynı sabitler aynı nesneyi paylaşır. Bellek kullanımı azalır, performans artar (dizgiler değiştirilemediği için güvenlidir).
new String(...)havuza tabi değildir: hernewyeni bir nesne demektir.- Bu yüzden
==, içeriği aynı sabitlerdetrue, içeriği aynınewnesnelerindefalsedöner. - Çalışma zamanında
+ile üretilen dizgi de yeni nesnedir; derleme zamanında hesaplanan"Gire" + "sun"ise havuza gider.s.intern()havuzdaki eşini verir.
İki dizgi sabiti tek nesneyi paylaşır; new ayrı bir nesne üretir.
Karşılaştırma · Adım adım kod izleme
Dizgi Havuzu: Adım Adım
Havuzda "Giresun" sabiti için bir nesne var; str1 onu gösterir.
Aynı sabit tekrar kullanılır: yeni nesne oluşmaz, str2 de aynı nesneyi gösterir.
new her zaman havuz dışında yeni bir nesne oluşturur (içerik aynı).
str1 ve str2 aynı nesne (#1) → true.
"Giresun" sabiti de havuzdaki #1 → true.
#1 ile #2 farklı nesneler (içerik aynı olsa da) → false.
#2 ile havuzdaki #1 farklı → false.
String str1 = "Giresun";
String str2 = "Giresun";
String str3 = new String("Giresun");
System.out.println(str1 == str2);
System.out.println(str1 == "Giresun");
System.out.println(str1 == str3);
System.out.println(str3 == "Giresun");Karşılaştırma
equals() ile İçerik Karşılaştırma
String str1 = "Giresun"; String str2 = "Giresun"; String str3 = new String("Giresun"); System.out.println(str1.equals(str2)); System.out.println(str1.equals("Giresun")); System.out.println(str1.equals(str3)); System.out.println(str3.equals("Giresun")); System.out.println(str3.intern() == str1); String a = "Gire"; String b = a + "sun"; // yeni nesne System.out.println(b == str1); System.out.println(b.equals(str1));
true true true true true false true
equals()içeriği karakter karakter karşılaştırır: ilk dördütrue.- Nesnenin nasıl oluştuğu (dizgi sabiti,
new, birleştirme,Scanner) sonucu etkilemez. - Kullanıcı girdisi çalışma zamanında oluşur:
girdi == "evet"neredeyse hepfalse.
String cevap = null; System.out.println("evet".equals(cevap)); // false System.out.println(cevap.equals("evet")); // hata!
Exception in thread "main" java.lang.NullPointerException:
Cannot invoke "String.equals(Object)" because "cevap" is nullSabiti öne yazmak ("evet".equals(cevap)) null değerine karşı güvenlidir.
Karşılaştırma
Karşılaştırma Metotları
| Metot | Döndürdüğü | Açıklama |
|---|---|---|
equals(str) | boolean | İçerik birebir aynı mı? |
equalsIgnoreCase(str) | boolean | Büyük/küçük harf farkını göz ardı ederek aynı mı? |
startsWith(str) | boolean | Dizgi verilen dizgi ile başlıyor mu? |
endsWith(str) | boolean | Dizgi verilen dizgi ile bitiyor mu? |
contains(str) | boolean | Verilen dizgi, dizginin içinde geçiyor mu? |
isEmpty() / isBlank() | boolean | Uzunluk 0 mı? / Yalnızca boşluk mu? (isBlank: Java 11+) |
compareTo(str) | int | Sözlük sırası: negatif (önce), 0 (eşit), pozitif (sonra). |
compareToIgnoreCase(str) | int | Harf büyüklüğünü göz ardı eden compareTo. |
Hepsi büyük/küçük harfe duyarlıdır (adında IgnoreCase olanlar hariç) ve null parametreyle equals/equalsIgnoreCase yalnızca false döndürür.
Karşılaştırma
Karşılaştırma Metotları: Örnek
String s = "Giresun Üni.";
System.out.println(s.startsWith("Gir")); // true
System.out.println(s.startsWith("Gır")); // false
System.out.println(s.endsWith("Üni.")); // true
System.out.println(s.endsWith("Üni")); // false
System.out.println(s.equalsIgnoreCase("Giresun Üni.")); // true
System.out.println(s.equalsIgnoreCase("Gıresun üni.")); // true
System.out.println(s.equalsIgnoreCase("GIresun Uni.")); // false
System.out.println(s.contains("Üni")); // true- Yorumlardaki sonuçlar programın gerçek çıktısıdır.
"Gır":ıileifarklı karakterlerdir →false."Üni": dizgi noktayla bitiyor →false.equalsIgnoreCasekarakterleri büyük harfe çevirerek karşılaştırır:ıvei'nin ikisi deIolur →"Gıresun üni."eşit sayılır."GIresun Uni.":UileÜfarklı harflerdir →false.
Karşılaştırma
compareTo: Sözlük Sırası
System.out.println("elma".compareTo("armut"));
System.out.println("armut".compareTo("elma"));
System.out.println("elma".compareTo("elma"));
System.out.println("Elma".compareTo("elma"));
System.out.println("Elma".compareToIgnoreCase("elma"));
System.out.println("ev".compareTo("evet"));
System.out.println("çay".compareTo("dut"));4 -4 0 -32 0 -2 131
a.compareTo(b):aönce gelirse negatif, eşitse 0, sonra gelirse pozitif.- İlk farklı karakterin Unicode kodları çıkarılır:
'e' − 'a'= 101 − 97 = 4. 'E' − 'e'= 69 − 101 = −32: büyük harfler küçüklerden önce gelir.- Biri diğerinin öneki ise uzunluk farkı döner:
"ev"vs"evet"→ 2 − 4 = −2. 'ç'(231) >'d'(100):compareToTürkçe alfabe sırasını bilmez, “çay” “dut”tan sonra gelir. Doğru Türkçe sıralama içinjava.text.Collatorkullanılır.- Sıralama (ör.
Arrays.sort) veif (a.compareTo(b) < 0)gibi kıyaslamalarda kullanılır.<,>işleçleri dizgilerle çalışmaz.
Karşılaştırma · Adım adım kod izleme
compareTo: İlk Farklı Karaktere Kadar
compareTo iki dizgiyi baştan başlayarak karakter karakter karşılaştırır.
k = 0: 'm' (109) ile 'm' (109) eşit, devam.
k = 1: 'a' ile 'a' eşit.
k = 2: 's' (115) ile 'v' (118) farklı: karşılaştırma burada biter.
Sonuç kodların farkı: 115 − 118 = −3. Negatif: "masa" önce gelir.
"kar" ile "karne": ilk 3 karakter eşit, kısa olanın karakterleri bitti.
Biri diğerinin öneki: uzunluk farkı döner, 3 − 5 = −2.
İlk karakterler farklı: 'Z' (90) − 'a' (97) = −7. Büyük harfler küçüklerden önce gelir: Z bile a'dan önce!
-3 -2 -7 yazılır.
String a = "masa", b = "mavi"; int r1 = a.compareTo(b); int r2 = "kar".compareTo("karne"); int r3 = "Zeki".compareTo("ali"); System.out.println(r1 + " " + r2 + " " + r3);
Biçimli Çıktı
printf Metodu
- Kullanım:
System.out.printf("biçim dizgisi", parametreler); - Biçim dizgisi, parametrelerin yerleşeceği biçim belirteçlerini (format specifier) içerir; parametreler sırayla yerleşir.
printfalt satıra geçmez: sona\nya da platformdan bağımsız%neklenir.- Genişlik:
%Wd→ W karakter, sağa hizalı;%-Wd→ W karakter, sola hizalı. - Hassasiyet:
%.2f→ virgülden sonra 2 basamak (yuvarlanır);%8.2f→ toplam 8 karakter. - Değer genişliğe sığmazsa kesilmez, alan genişler.
| Biçim belirteci | Tip | Örnek → çıktı |
|---|---|---|
%d | Tam sayı | 42 → 42 |
%f | Ondalık (float, double) | %.1f: 3.14159 → 3,1 |
%s | Dizgi | %5s: "ab" → ␣␣␣ab |
%c | Karakter | 'Z' → Z |
%b | Mantıksal | true → true |
%n | Yeni satır | — |
Ondalık ayırıcı yerel ayara bağlıdır: tr-TR'de 3,1, Locale.US ile 3.1.
Biçimli Çıktı
printf: Örnek
int i = 3; float f = -17; String s = "java"; System.out.printf("x: %d y: %f s: %s\n", i, f, s); System.out.printf("x: %4d y: %5.2f s: %6s\n", i, f, s); System.out.printf("x: %-4d y: %-7.2f s: %-6s\n", i, f, s); System.out.printf("x: %-4d y: %-6.3f s: %-6s\n", i, f, s);
x: 3 y: -17,000000 s: java x: 3 y: -17,00 s: java x: 3 y: -17,00 s: java·· x: 3 y: -17,000 s: java··
%fvarsayılan olarak 6 ondalık basamak yazar:-17,000000. Türkçe ayarda ondalık ayırıcı virgüldür.%5.2f:-17,00zaten 6 karakter olduğu için 5 genişlik etkisizdir.%-6.3f:-17,0007 karakterdir, alan genişler.%6s→␣␣java(sağa hizalı);%-6s→java␣␣(sola hizalı, sona boşluk eklenir).
Biçimli Çıktı · Adım adım kod izleme
Genişlik ve Hassasiyet: Karakter Karakter
Genişlik verilmezse her değer kendi uzunluğu kadar yer kaplar; %f 6 ondalık basamak yazar.
%4d ve %6s değeri sağa yaslar, solu boşlukla doldurur. -17,00 6 karakter: 5 genişliğe sığmaz, alan büyür.
Eksi işareti sola hizalar: boşluklar değerin sağına eklenir. Sütunlar alt alta düzgün hizalanır.
%-6.3f: 3 ondalık → -17,000 7 karakter; genişlik 6'dan büyük olduğu için dolgu yapılmaz.
int i = 3; float f = -17; String s = "java"; System.out.printf("x: %d y: %f s: %s\n", i, f, s); System.out.printf("x: %4d y: %5.2f s: %6s\n", i, f, s); System.out.printf("x: %-4d y: %-7.2f s: %-6s\n", i, f, s); System.out.printf("x: %-4d y: %-6.3f s: %-6s\n", i, f, s);
Biçimli Çıktı
Diğer Biçimler ve String.format
System.out.printf("|%5s|%-5s|%05d|%.1f|%n", "ab", "ab", 42, 3.14159);
System.out.printf("%c %b %e %x %%%n", 'Z', true, 1234.5, 255);
String mesaj = String.format("%s: %d puan", "Ayşe", 85);
System.out.println(mesaj);
System.out.printf("%,d%n", 1234567);
System.out.printf(Locale.US, "%.2f%n", 2.5); // import java.util.Locale;
System.out.println("%s = %d".formatted("x", 7)); // Java 15+| ab|ab |00042|3,1| Z true 1,234500e+03 ff % Ayşe: 85 puan 1.234.567 2.50 x = 7
%05dbaşa sıfır doldurur,%,dbinlik ayırıcı koyar (tr-TR: nokta),%ebilimsel,%xonaltılık gösterim,%%yüzde işaretidir.String.format(...)aynı kuralları kullanır ama ekrana yazmak yerine biçimlenmiş dizgiyi döndürür.- İlk parametre bir
Localeolabilir:Locale.USile ondalık ayırıcı noktadır. - Tip uyuşmazlığı çalışma zamanında hatadır:
printf("%d", 3.5)→IllegalFormatConversionException.
Uygulamalar · Adım adım kod izleme
Palindrom Kontrolü: Adım Adım
Kullanıcının girdiği metin: "Kayak".
toLowerCase() ile küçük harfe çevrilir (yeni nesne metin'e atanır).
Sonuç için boş bir dizgi hazırlanır.
i = 4: charAt(4) = 'k' sona eklenir → "k".
i = 3: charAt(3) = 'a' sona eklenir → "ka".
i = 2: charAt(2) = 'y' sona eklenir → "kay".
i = 1: charAt(1) = 'a' sona eklenir → "kaya".
i = 0: charAt(0) = 'k' sona eklenir → "kayak".
i = -1: -1 >= 0 yanlış, döngü biter.
Ters çevrilmiş metin yazdırılır.
İçerikler aynı: equals → true, “kayak” bir palindromdur.
String metin = "Kayak"; metin = metin.toLowerCase(); String ters = ""; for (int i = metin.length() - 1; i >= 0; i--) { ters += metin.charAt(i); } System.out.println(ters); System.out.println(metin.equals(ters));
Palindrom: tersten okunuşu aynı olan metin (kayak, ana, kek). Cümlelerde önce harf olmayanlar silinir: metin.replaceAll("[^\\p{L}]", "") (yalnızca harfler kalır). Ters çevirmenin kısa yolu: new StringBuilder(metin).reverse().toString(); “Ey Edip Adana'da pide ye” temizlenince palindromdur.
Uygulamalar
Uygulama: Kelime Frekansı
String metin = "Bir iki bir üç İki bir";
String[] kelimeler = metin.toLowerCase().split(" ");
boolean[] sayildi = new boolean[kelimeler.length];
for (int i = 0; i < kelimeler.length; i++) {
if (sayildi[i]) {
continue; // bu kelime daha önce sayıldı
}
int frekans = 1;
for (int j = i + 1; j < kelimeler.length; j++) {
if (kelimeler[i].equals(kelimeler[j])) {
frekans++;
sayildi[j] = true;
}
}
System.out.println(kelimeler[i] + ": " + frekans);
}bir: 3 iki: 2 üç: 1
toLowerCase()sayesinde “Bir/bir” ve “İki/iki” aynı kelime sayılır (tr-TR'deİ→i).split(" ")metni kelimelere böler.- Kelimeler
equalsile karşılaştırılır:split'in ürettiği parçalar ayrı nesnelerdir,==yanlış sonuç verir. sayildidizisi, aynı kelimenin ikinci kez raporlanmasını engeller.
Uygulamalar · Adım adım kod izleme
Kelime Frekansı: Bayraklarla Sayma
Küçük harfe çevrilip boşluklardan bölünür: 5 kelimelik dizi. "Armut" ve "ARMUT" artık aynı.
sayildi: her kelime için bir bayrak, hepsi false.
i = 0 (elma): iç döngü sağdaki kelimeleri equals ile tarar; j = 2 eşit → frekans 2, sayildi[2] = true.
elma: 2 yazılır.
i = 1 (armut): j = 4 eşit → frekans 2, sayildi[4] = true.
armut: 2 yazılır.
i = 2: bayrak true, bu elma zaten sayıldı → continue.
i = 3 (kiraz): eşi yok, frekans 1.
i = 4: zaten sayıldı, atlanır. Döngü biter.
String metin = "elma Armut elma kiraz ARMUT";
String[] k = metin.toLowerCase().split(" ");
boolean[] sayildi = new boolean[k.length];
for (int i = 0; i < k.length; i++) {
if (sayildi[i]) continue;
int frekans = 1;
for (int j = i + 1; j < k.length; j++) {
if (k[i].equals(k[j])) {
frekans++;
sayildi[j] = true;
}
}
System.out.println(k[i] + ": " + frekans);
}Özet
Özet
| Kavram | Özü |
|---|---|
String | Karakter dizisini saklayan, değiştirilemez nesne; dizgi sabiti ("...") ya da new ile oluşur. |
| İndis | 0 … length() - 1; charAt(i) bir char döndürür. |
+ | Soldan sağa: bir yan dizgiyse birleştirme; sayıları toplamak için parantez. |
| Metotlar | indexOf (−1 = yok), substring(a, b) (b hariç), toUpperCase, replace, split, trim… hepsi yeni değer döndürür. |
StringBuilder | Döngüde çok birleştirme için değiştirilebilir tampon. |
Scanner | next() kelime, nextLine() satır; nextInt() sonrası ⏎ tamponda kalır. |
== / equals | Aynı nesne mi? / Aynı içerik mi? Dizgiler için daima equals. |
| Dizgi havuzu | Aynı dizgi sabitleri tek nesneyi paylaşır; new ve çalışma zamanı birleştirmesi yeni nesne üretir. |
| Karşılaştırma | equalsIgnoreCase, startsWith, endsWith, contains, compareTo (Unicode sırası). |
printf | %d %f %s; %Wd sağa, %-Wd sola hizalı; %.2f hassasiyet; ayırıcılar yerel ayara bağlı. |
Özet
İlgili Sayfalar
Simülatör: dizgi sabitleri, new String, intern() ve ==/equals farkı; StringBuilder tamponunun yerinde değişmesi adım adım.
Birleştirme sırası, substring ve indexOf, havuz, Scanner tamponu, printf ve palindrom soruları.
Özet
Sık Yapılan Hatalar (1): Derleyici Hataları
error: unclosed character literalString s = 'Merhaba'; Tek tırnak yalnızca tek karakter içindir; dizgi çift tırnakla yazılır.error: incompatible types: String cannot be converted to charchar c = "a"; yerine char c = 'a'; ya da "a".charAt(0).error: cannot find symbol symbol: variable lengthDizgide s.length() metottur. Tersi de hatadır: dizide d.length() → symbol: method length().error: cannot find symbol symbol: class stringSınıf adı String'dir; Java büyük/küçük harfe duyarlıdır.error: incompatible types: String cannot be converted to intint n = "42"; yerine Integer.parseInt("42").error: unexpected type required: variables.charAt(0) = 'j'; yazılamaz: dizgi değiştirilemez. Çözüm: yeni dizgi oluşturmak ya da StringBuilder.setCharAt.Özet
Sık Yapılan Hatalar (2): Mantık ve Çalışma Zamanı
if (girdi == "evet") // derlenir ama yanlışKullanıcı girdisi yeni bir nesnedir; koşul false çıkar. Doğrusu "evet".equals(girdi).s.toUpperCase(); // s değişmezDizgi değiştirilemez; s = s.toUpperCase(); yazılmalıdır.StringIndexOutOfBoundsException: Index 4 out of bounds for length 4Son karakter s.charAt(s.length() - 1); döngü koşulu i < s.length().String ad = klavye.nextLine(); // ""Artakalan ⏎ okunur. Çözüm: araya bir klavye.nextLine();.NullPointerException: Cannot invoke "String.equals(Object)"Sabit öne yazılırsa hata olmaz: "evet".equals(cevap).s.substring(5, 12) // 7 karakterBitiş indisi hariçtir: uzunluk = bitiş − başlangıç.Özet
Örnek Problemler (1)
Problem 1. Ne yazdırır?
String s = "Karadeniz";
s.toUpperCase();
String t = s.substring(2, 5);
System.out.println(t + " " + t.length());
System.out.println(s.indexOf("de"));
System.out.println(s.indexOf("x"));
System.out.println(1 + 2 + "3" + 4 + 5);Problem 2. Ne yazdırır?
String a = "ders";
String b = "de" + "rs";
String c = new String("ders");
String d = c;
System.out.println(a == b);
System.out.println(a == c);
System.out.println(c == d);
System.out.println(a.equals(c));Cevapları göster
- rad 3 / 4 / -1 / 3345.
toUpperCase()'nin sonucu atanmadığı içinsdeğişmez.substring(2, 5)→ indis 2, 3, 4 = "rad" (3 karakter). "de" indis 4'te başlar; "x" yok → −1. Son satır soldan sağa: 1 + 2 = 3, sonra "3" ile birleşir → "33", ardından "334", "3345". - true / false / true / true.
"de" + "rs"derleme zamanında hesaplanan bir sabittir → havuzdakiaile aynı nesne.cnewile ayrı nesne;d = caynı referans. İçerikler aynı olduğu içinequalstrue.
Özet
Örnek Problemler (2)
Problem 3. Çıktıyı karakter karakter yazın (tr-TR).
String ad = "Ali";
double not1 = 72.456;
System.out.printf("[%-5s][%3d][%7.2f]%n", ad, 7, not1);Problem 4. Ne yazdırır?
public static String bas(String ad, String soyad) { return ad.charAt(0) + "." + soyad.charAt(0) + "."; } System.out.println(bas("Sercan", "Külcü")); String e = "ogrenci@giresun.edu.tr"; int at = e.indexOf('@'); System.out.println(e.substring(0, at)); System.out.println(e.substring(at + 1));
Cevapları göster
[Ali ][ 7][ 72,46].%-5s: "Ali" + 2 boşluk;%3d: 2 boşluk + "7";%7.2f: "72,46" (yuvarlanır) + başta 2 boşluk.- S.K. / ogrenci / giresun.edu.tr.
char + "."bir dizgidir, birleştirme yapılır (ikichartoplansaydı sayı çıkardı).@indis 7'de:substring(0, 7)vesubstring(8).
Özet
Alıştırmalar (1)
tersCevir(String s)metodunu yazın:tersCevir("Giresun")→"nuseriG".say(String s, char aranan): karakterin kaç kez geçtiğini döndürsün.say("Karadeniz", 'a')→ ?basHarfBuyuk(String kelime): ilk harf büyük, gerisi küçük.basHarfBuyuk("jAVA")→"Java".
Cevapları göster
static String tersCevir(String s) { String ters = ""; for (int i = s.length() - 1; i >= 0; i--) { ters += s.charAt(i); } return ters; }
static String basHarfBuyuk(String kelime) { return kelime.substring(0, 1).toUpperCase() + kelime.substring(1).toLowerCase(); }
static int say(String s, char aranan) { int adet = 0; for (int i = 0; i < s.length(); i++) { if (s.charAt(i) == aranan) { adet++; } } return adet; }
Çıktılar: nuseriG · 2 · Java. char değerleri == ile karşılaştırılabilir (ilkel tip); Karadeniz → 2.
Özet
Alıştırmalar (2)
"Java ile nesne yönelimli programlama"cümlesinde kaç kelime vardır? Tek satırda bulun.- Bir kelimedeki sesli harfleri sayan programı yazın (Türkçe sesliler dahil).
"Ordu"→ ? - Kullanıcıdan önce yaş, sonra ad-soyad isteyen ve
printfile “Ad: …, Yaş: …” yazan programınextInttuzağına düşmeden yazın.
Cevapları göster
String kelime = "Ordu"; String sesliler = "aeıioöuüAEIİOÖUÜ"; int sayac = 0; for (int i = 0; i < kelime.length(); i++) { char c = kelime.charAt(i); if (sesliler.indexOf(c) != -1) { sayac++; } } System.out.println("Sesli: " + sayac);
4) cumle.split(" ").length → 5. 5) Çıktı: Sesli: 2 (O, u).
Scanner k = new Scanner(System.in); System.out.print("Yaş: "); int yas = k.nextInt(); k.nextLine(); // satır sonunu at System.out.print("Ad: "); String ad = k.nextLine(); System.out.printf("Ad: %s, Yaş: %d%n", ad, yas);
Yaş: 20 Ad: Ali Veli Ad: Ali Veli, Yaş: 20
Özet
Kaynaklar
- Oracle, The Java Tutorials: “Strings”, “Comparing Strings and Portions of Strings”, “The StringBuilder Class”, “Formatting Numeric Print Output”.
- Oracle, Java SE 21 API Documentation:
java.lang.String,java.lang.StringBuilder,java.util.Scanner,java.util.Formatter,java.util.Locale. - J. Gosling ve diğ., The Java Language Specification, Java SE 21 Edition (§3.10.5 String Literals, §15.18.1 String Concatenation Operator +).
- P. Deitel ve H. Deitel, Java: How to Program, 11. baskı, Pearson, 2017 (Bölüm 14: Strings, Characters and Regular Expressions).
- C. S. Horstmann, Core Java, Volume I: Fundamentals, 12. baskı, 2022 (Bölüm 3.6: Strings).
- A. B. Downey ve C. Mayfield, Think Java, 2. baskı, O'Reilly, 2019 (Bölüm 6: Loops and Strings).