Dizgiler

Bilgisayar ve Programlamaya Giriş
StringİndeksMetotlarKarşılaştırmaBiçimleme
Sercan KÜLCÜ · Giresun Üniversitesi

Giriş

Öğrenme Çıktıları

Temsil

String ve char ayrımını açıklamak.

İşleme

İndeks ve temel metotları kullanmak.

Karşılaştırma

İçerik ve başvuru karşılaştırmasını ayırmak.

Çıktı

printf ile biçimli metin üretmek.

Temeller

String Nedir?

  • String, karakter dizisini temsil eden java.lang sınıfıdır (import gerekmez).
  • Dizgi sabitleri çift tırnakla ("Tarkan"), char tek tırnakla ('T') yazılır.
  • String ilkel tür değil, değiştirilemez bir nesnedir; değişken nesnenin başvurusunu tutar.
YığınHeapad0T1a2r3k4a5nString nesnesi: karakter dizisic'T'char: tek karakter, değer doğrudan

Temeller

String Oluşturma

String ad = "Tarkan";
String boş = "";
String kopya = new String(ad);
String yok = null;
  • Çoğunlukla new kullanmadan dizgi sabiti tercih edilir.
  • "" uzunluğu 0 olan gerçek bir nesnedir; null ise hiçbir nesneyi göstermez (yok.length() → NullPointerException).
YığınHeapString havuzu (sabitler)Tarkan""uzunluk 0Tarkannew → ayrı nesneadboşkopyayoknull

Temeller

Değişmezlik

  • String oluşturulduktan sonra içeriği değişmez.
  • Birleştirme ve dönüştürme işlemleri yeni String üretir; eski nesne olduğu gibi kalır.
  • Sonucu kullanmak için dönen değer bir değişkene atanmalıdır.
  • Hiçbir değişkenin göstermediği nesneyi çöp toplayıcı (garbage collector) temizler.
YığınHeapMerhabas

String s = "Merhaba";

YığınHeapMerhabadeğişmediMerhaba!yenis

s = s + "!"; → yeni nesne; ok ona taşındı, eski nesne aynı.

Temeller · Kodu adım adım çalıştır

Değişmezlik: toUpperCase()

YığınHeapString havuzu (sabitler)javadil

dil, havuzdaki "java" nesnesini gösterir.

YığınHeapString havuzu (sabitler)javaJAVAkimse göstermiyordil

toUpperCase() yeni bir "JAVA" nesnesi üretir; ama sonuç hiçbir değişkene atanmadı → kaybolur. dil hâlâ eski nesnede.

YığınHeapString havuzu (sabitler)javaJAVAçöpdil

Eski nesne değişmediği için java yazar.

YığınHeapString havuzu (sabitler)javaJAVAyeni nesnedil

Bu kez dönen yeni nesne dil'e atanır: ok yeni nesneye taşınır. "java" nesnesi yine aynen durur.

YığınHeapString havuzu (sabitler)javaJAVAdil

JAVA yazar. Değişen nesne değil, değişkenin gösterdiği yerdir.

String dil = "java";
dil.toUpperCase();
System.out.println(dil); // java
dil = dil.toUpperCase();
System.out.println(dil); // JAVA

İndeks

İndeksleme

0G1i2r3e4s5u6nss.length() = 7s.charAt(0) → 'G's.charAt(6) → 'n'7✗
  • İlk karakter 0, son karakter length() − 1 indeksindedir; length() bir metottur (dizilerdeki length alanından farklı).
  • charAt(i) o konumdaki char değerini döndürür; charAt(7) → StringIndexOutOfBoundsException.

Metotlar · Kodu adım adım çalıştır

Temel Metotlar

0J1a2v3a4␣5P6r7o8g9r10a11m12l13a14m15a

16 karakterlik dizgi (boşluk da bir karakterdir: indeks 4).

0J1a2v3a4␣5P6r7o8g9r10a11m12l13a14m15a

length() → 16; indeksler 0 … 15.

0J1a2v3a4␣5P6r7o8g9r10a11m12l13a14m15a▲ konum

indexOf aranan metnin ilk karakterinin indeksini verir → 5 (yoksa −1).

0J1a2v3a4␣5P6r7o8g9r10a11m12l13a14m15a

substring(5, 16): 5 dahil, 16 hariç → 11 karakter: "Programlama".

0J1a2v3a4␣5P6r7o8g9r10a11m12l13a14m15a

contains("Java") → true. Hiçbir metot s'yi değiştirmedi.

0J1a2v3a4␣5P6r7o8g9r10a11m12l13a14m15a

Sonuçlar birleştirilip yazdırılır.

String s = "Java Programlama";
int uzunluk = s.length();
int konum = s.indexOf("Programlama");
String alt = s.substring(5, 16);
boolean içerir = s.contains("Java");
System.out.println(alt + " " + konum);

Metotlar

Sık String Metotları

MetotSonuç
length()Karakter/kod birimi sayısı
charAt(i)i konumundaki char
substring(a,b)a dahil, b hariç alt dizgi
indexOf(x)İlk konum veya -1
toLowerCase()Küçük harfli yeni String
trim() / strip()Kenar boşlukları kaldırılmış yeni String

Metotlar

Alt Dizgi Sınırları: s = "PROGRAM"

PROGRAM01234567s.substring(0, 3) → "PRO"

İndeksleri karakterlerin arasındaki çizgiler gibi düşünün: 0 ile 3 arası "PRO". Uzunluk = 3 − 0.

PROGRAM01234567s.substring(3, 7) → "GRAM"

Bitiş length() = 7 olabilir: son karakter dahil edilir.

PROGRAM01234567s.substring(3) → "GRAM"

Tek parametreli sürüm: başlangıçtan sona kadar.

PROGRAM01234567s.substring(2, 2) → ""

Başlangıç = bitiş → boş dizgi "" (hata değil).

PROGRAM01234567✗ 9 yoks.substring(5, 9) → StringIndexOutOfBoundsException

Bitiş > length() ya da başlangıç > bitiş → çalışma zamanı hatası.

  • substring(a, b): a dahil, b hariç; sonuç uzunluğu b − a.
  • Geçerli aralık: 0 ≤ a ≤ b ≤ length().

Metotlar · Kodu adım adım çalıştır

Uygulama: E-postayı Parçalama

0a1l2i3@4g5r6u7.8e9d10ueposta

11 karakterlik e-posta adresi; kullanıcı adını ve alan adını ayıracağız.

0a1l2i3@4g5r6u7.8e9d10u▲ ateposta

indexOf('@') → 3: ayırıcının konumu.

0a1l2i3@4g5r6u7.8e9d10u▲ ateposta

substring(0, 3): 0 dahil, 3 (@) hariç → "ali".

0a1l2i3@4g5r6u7.8e9d10u▲ ateposta

substring(4): @'den sonraki karakterden sona kadar → "gru.edu".

0a1l2i3@4g5r6u7.8e9d10ueposta

charAt(0) bir char döndürür: 'a' (tek tırnak).

0a1l2i3@4g5r6u7.8e9d10ueposta

Parçalar birleştirilerek yazdırılır.

0a1l2i3@4g5r6u7.8e9d10ueposta

Character.toUpperCase char'ı büyük harfe çevirir → A. eposta hiç değişmedi.

String eposta = "ali@gru.edu";
int at = eposta.indexOf('@');
String kullanıcı = eposta.substring(0, at);
String alan = eposta.substring(at + 1);
char ilk = eposta.charAt(0);
System.out.println(kullanıcı + " / " + alan);
System.out.println(Character.toUpperCase(ilk));

Karşılaştırma · Kodu adım adım çalıştır

== ile equals Farkı

YığınHeapString havuzu (sabitler)Giresuna

Sabit "Giresun" String havuzuna konur; a onu gösterir.

YığınHeapString havuzu (sabitler)GiresunGiresunnew ile ayrı nesneab

new String(...) içerik aynı olsa da heap'te ayrı bir nesne açar.

YığınHeapString havuzu (sabitler)GiresunGiresunnew ile ayrı nesneabc

Aynı sabit tekrar yazıldı: havuzdaki mevcut nesne paylaşılır → c ile a aynı oku taşır.

YığınHeapString havuzu (sabitler)GiresunGiresunnew ile ayrı nesneabc

a == b: iki ok farklı nesneye gidiyor → false (içeriğe bakılmaz).

YığınHeapString havuzu (sabitler)GiresunGiresunnew ile ayrı nesneabc

a == c: iki ok aynı nesnede → true.

YığınHeapString havuzu (sabitler)GiresunGiresunnew ile ayrı nesneabc

equals karakterleri tek tek karşılaştırır: G=G, i=i, … → true. İçerik için daima equals.

String a = "Giresun";
String b = new String("Giresun");
String c = "Giresun";
System.out.println(a == b);      // false
System.out.println(a == c);      // true
System.out.println(a.equals(b)); // true

Karşılaştırma

Karşılaştırma Metotları

MetotAmaçÖrnek
equalsİçerik eşitliği"abc".equals("abc") → true
equalsIgnoreCaseBüyük-küçük harfi yok sayan eşitlik"Java".equalsIgnoreCase("JAVA") → true
startsWithBelirli metinle başlama"Giresun".startsWith("Gir") → true
endsWithBelirli metinle bitme"Giresun".endsWith("sun") → true
compareToSözlüksel sıra: <0, 0, >0"elma".compareTo("armut") → pozitif

compareTo Unicode değerlerine göre çalışır: büyük harfler küçüklerden önce gelir ve Türkçe harfler (ç, ğ, ı, ö, ş, ü) alfabe sırasına uymayabilir.

Bellek

String Havuzu

  • Aynı dizgi sabitleri havuzdaki tek bir nesneyi paylaşır (bellek tasarrufu; değişmezlik sayesinde güvenli).
  • new String(...) her zaman ayrı nesne oluşturur.
  • Bir String'in havuzdan mı geldiği koda bakınca her zaman anlaşılmaz; bu yüzden içerik karşılaştırmasında == değil equals kullanılır.
YığınHeapString havuzu (sabitler)GiresunpaylaşılırGiresunnewacb

Girdi

Scanner ile Metin Girdisi

import java.util.Scanner;
// ...
Scanner klavye = new Scanner(System.in);
String kelime = klavye.next();
klavye.nextLine();
String satır = klavye.nextLine();
  • next() bir kelime okur: baştaki boşlukları atlar, ilk boşlukta/satır sonunda durur.
  • nextLine() satır sonuna (⏎) kadar her şeyi okur ve ⏎'ı tüketir.
  • next() veya nextInt() sonrası tamponda kalan ⏎, bir nextLine() ile ayrıca tüketilmelidir.

Girdi · Kodu adım adım çalıştır

Kod İzleme: next() ve nextLine()

Klavye tamponu (System.in)▲ okuma konumu

Scanner klavye akışına bağlanır; tampon şimdilik boş.

Klavye tamponu (System.in)Ada⏎▲ okuma konumu

next() okuyacak bir şey bulamaz ve bekler. Kullanıcı Ada yazıp Enter'a basar → tampona "Ada⏎" girer.

Klavye tamponu (System.in)Ada⏎▲ okuma konumu

next() boşluk/satır sonuna kadar okur → "Ada". ⏎ tamponda kalır.

Klavye tamponu (System.in)Ada⏎▲ okuma konumu

nextLine() ⏎'a kadar okur → "" (boş) döner ve ⏎'ı tüketir. Artık tampon temiz.

Klavye tamponu (System.in)Ada⏎Giresun␣Merkez⏎▲ okuma konumu

Tampon boş → nextLine() bekler. Kullanıcı Giresun Merkez yazıp Enter'a basar.

Klavye tamponu (System.in)Ada⏎Giresun␣Merkez⏎▲ okuma konumu

Satırın tamamı (boşluk dahil) okunur → "Giresun Merkez"; ⏎ tüketilir ama sonuca eklenmez.

Klavye tamponu (System.in)Ada⏎Giresun␣Merkez⏎▲ okuma konumu

İki değer yazdırılır.

Scanner klavye = new Scanner(System.in);
String kelime = klavye.next();
klavye.nextLine();
String satır = klavye.nextLine();
System.out.println(kelime + " | " + satır);

3. satır olmasaydı 4. satırdaki nextLine() kalan ⏎'ı okuyup hemen boş satır döndürürdü.

Performans

Birleştirme ve StringBuilder

  • + az sayıda birleştirme için okunaklıdır.
  • Döngüde s = s + x her turda yeni String oluşturur ve eskiyi kopyalar.
  • StringBuilder değiştirilebilir bir tampondur: append aynı nesneye ekler.
  • toString() tamponun o anki içeriğinden son String'i üretir.
String + (döngüde)1␣çöp1␣2␣çöp1␣2␣3␣yeni nesneStringBuilder1␣2␣3␣tek nesne

Performans · Kodu adım adım çalıştır

Kod İzleme: StringBuilder ile Birleştirme

YığınHeap""StringBuilder (değişebilir)metin

Boş, değiştirilebilir bir tampon oluşturulur.

YığınHeap""StringBuilder (değişebilir)metin

1 <= 3 → true

YığınHeap1␣StringBuilder (değişebilir)metin

append(1) ve append(' ') aynı nesneye ekler (yeni String yok) → "1 ".

YığınHeap1␣StringBuilder (değişebilir)metin

i++ → 2 <= 3 → true

YığınHeap1␣2␣StringBuilder (değişebilir)metin

append(2) ve append(' ') aynı nesneye ekler (yeni String yok) → "1 2 ".

YığınHeap1␣2␣StringBuilder (değişebilir)metin

i++ → 3 <= 3 → true

YığınHeap1␣2␣3␣StringBuilder (değişebilir)metin

append(3) ve append(' ') aynı nesneye ekler (yeni String yok) → "1 2 3 ".

YığınHeap1␣2␣3␣StringBuilder (değişebilir)metin

i++ → 4 <= 3 → false: döngü biter.

YığınHeap1␣2␣3␣StringBuilder (değişebilir)1␣2␣3␣Stringmetinsonuç

toString() tampondan tek bir String üretir.

YığınHeap1␣2␣3␣StringBuilder (değişebilir)1␣2␣3␣Stringmetinsonuç

Sondaki boşluk görünsün diye | eklendi.

StringBuilder metin = new StringBuilder();
for (int i = 1; i <= 3; i++) {
    metin.append(i).append(' ');
}
String sonuç = metin.toString();
System.out.println(sonuç + "|");

Biçimleme

printf ile Biçimleme

System.out.printf("%-8s %3d %7.2f%n", ad, adet, fiyat);
%-8s␣%3d␣%7.2f%n"%-8s %3d %7.2f%n" (biçim dizgisi)ad"Java"adet3fiyat17.5çıktı:Java␣␣␣␣sola yaslı, 8 genişlik␣␣␣3␣␣␣17.50

%-8s ← ad: "Java" 8 hücreye sola yaslanır, kalan 4 hücre boşluk.

%-8s␣%3d␣%7.2f%n"%-8s %3d %7.2f%n" (biçim dizgisi)ad"Java"adet3fiyat17.5çıktı:Java␣␣␣␣␣␣␣3sağa yaslı, 3 genişlik␣␣␣17.50

%3d ← adet: 3 tam sayısı 3 hücreye sağa yaslanır.

%-8s␣%3d␣%7.2f%n"%-8s %3d %7.2f%n" (biçim dizgisi)ad"Java"adet3fiyat17.5çıktı:Java␣␣␣␣␣␣␣3␣␣␣17.507 genişlik, 2 ondalık

%7.2f ← fiyat: 2 ondalıkla "17.50" (5 karakter) 7 hücreye sağa yaslanır.

%-8s␣%3d␣%7.2f%n"%-8s %3d %7.2f%n" (biçim dizgisi)ad"Java"adet3fiyat17.5çıktı:Java␣␣␣␣␣␣␣3␣␣␣17.50⏎satır sonu

%n satır sonu ekler. Belirteçler argümanlarla sırayla eşleşir; tür uyuşmazsa hata oluşur.

%s metin, %d tam sayı, %f ondalıklı sayı. Türkçe yerel ayarlı bilgisayarda %.2f ondalık ayırıcı olarak virgül basabilir (17,50).

Temeller

Unicode ve Metin

  • String UTF-16 kod birimlerinden oluşur.
  • Bazı görünür karakterler iki char veya birden fazla Unicode kod noktası içerebilir.
  • Kullanıcıya görünen karakter sayısı için yalnızca length her durumda yeterli olmayabilir.

Özet

Bölüm Özeti

  • String değiştirilemez bir nesnedir; işlemler yeni String döndürür.
  • İndeksler 0'dan length()-1'e uzanır.
  • İçerik karşılaştırması equals ile, sözlüksel sıra compareTo ile yapılır.
  • Yoğun birleştirmede StringBuilder; biçimli çıktıda printf kullanılabilir.

Özet

Kontrol Soruları

  1. String neden değiştirilemez olarak adlandırılır?
  2. substring başlangıç ve bitiş sınırlarını nasıl kullanır?
  3. == ile equals arasındaki fark nedir?
  4. next ve nextLine nasıl ayrılır?
  5. Döngü içinde neden StringBuilder tercih edilebilir?

Son

Dizgiler
1 / 1Sercan KÜLCÜ, Tüm hakları saklıdır.

← → veya boşluk ile gezinin · F: tam ekran · Home/End: ilk/son slayt