Java Bir Stringin Anatomisi

'Diğer Programlama Dilleri' forumunda acemihacker tarafından 2 Temmuz 2018 tarihinde açılan konu

  1. acemihacker

    acemihacker Ötüken Yolcusu Bronz Üye

    Mesaj:
    205
    Beğeniler:
    74
    Cinsiyet:
    Erkek
    Merhabalar enteresan bir başlığa sahip bu yazımda size Java programlama dilinde stringlerden bahsedeceğim. Aslında ilgi çeksinde birileri konuya girsin diye böyle bir başlık koydum, girip okuyanlara ne mutlu.
    Buraya kadar geldiyseniz sizlere bir şeyler öğretmek boynumun borcu oldu. Bu hayatta en önemli şeylerden birisi zamandır ve zamanımızı nasıl değerlendireceğimiz bize bağlıdır. Oturup "abi feys nasıl heyklerim ?" diye konu açıp okumak veya literatürde bulunan kavramları öğrenmek işte bütün mesele bu...
    Her neyse. Bu akşam canım sıkılıyor çok sitem dolu bir yazı olmasın.

    Hemen birkaç soru ile başlayalım :

    Kod:
    String isim = new String("acemihacker");
    String ikinciIsim = "acemihacker";
    
    boolean esitMi(String a, String b){
    return a==b ? true : false;
    }
    
    esitMi(isim , ikinciIsim);

    1 - ) Yukarıda yazdığım kodu çalıştırdığımızda sizce dönen cevap "true" mu olur "false" mu ? Vereceğiniz cevabı yorum olarak soru numarasını ekleyerek yazın, hemen göndermeyin, sıradaki sorularıda aynı şekilde cevaplayın.
    Şu kodu da bir inceleyelim :

    Kod:
    String isim = new String("ihan3t");
    String ikinciIsim = "acemihacker";
    
    boolean esitMi(String a, String b){
    return a.equalsIgnoreCase(b);
    }
    
    esitMi(isim , ikinciIsim);
    

    2 - ) Peki bu kod bloğunun çıktısı ne olur "true" vs "false" ? Bununda cevabını 2 numaralı cevap olarak yorumunuza ekleyin.
    Şimdi cevapları ben söyleyeyim, birçoğunuz muhtemelen ikisininde çıktısının "true" olmasını bekliyor. Ama hayır, ilk sorunun cevabı "false". Evet, cevap "false". İkincisinin cevabı ise tahmin ettiğiniz üzere "true".

    Peki neden ilkinin cevabı false çıkarken ikincisi true çıkıyor ? İlkinde neden false çıkıyor ?

    Şimdi şöyle ki, == operatörü nesnelerin eşitliğini kontrol eder. Yani bellekte aynı yeri işaret edip etmediğini kontrol eder.

    1- Peki neden bu iki string aynı değere sahip olmalarına rağmen bellekte farklı yeri işaret ediyorlar ?

    2- Acaba bu iki string belleğin aynı bölgesinde mi bulunuyor ?

    3- İki stringin (veya nesnenin) aynı bellek bölgesini işaret etmesini nasıl sağlarız ?


    Cevap 1,2 - ) Javada stringler belleğin 2 farklı yerinde tutulur, String Pool dediğimiz bölüm ve heap bölümü. Aslında String Pool bölümü heap'in içinde oluşturulmuş bir alandır. Performans kazanmak amacıyla stringler için böyle bir yapı sağlanmıştır.

    String isim = "foo"; dediğimizde bu değer String Pool da tutulur. String isim = new String("foo"); dediğimizde ise bu değer direkt olarak heap'te tutulur. Dolayısıyla farklı bellek adreslerini işaret ederler.

    Cevap 3 - ) Öncelikle ilk akla gelen yöntem olarak degisken1 = degisken2; diyerek aynı adresi işaret etmesini sağlayabiliriz. Birde stringlerin özel bir metodu olan "intern" metodunu kullanacağız.

    Peki ne yapar bu "intern" metodu ? Intern metodu string poolda olmayan bir stringi poolda oluşturmaya veya eğer zaten değer bu havuzda varsa nesneleri eşleştirmeyi sağlar.

    Örnek verecek olursak :
    Kod:
      String isim = new String("acemihacker");
            String ikinciIsim = "acemihacker";
            String ucuncuIsim = isim.intern();
    
            System.out.println(isimUc == isim ? true : false);
            System.out.println(isimUc == ikinciIsim ? true : false);
    Kodu çalıştırdığımızda çıktılar sırasıyla "false" ve "true" olacaktır. Sebebi ise, intern metodu ucuncuIsim nesnesini String Poolda var olan "ikinciIsim" değişkeninin adresini göstermesini sağladı.

    Farklı bir şey deneyelim. İki farklı stringi birleştirip başka bir stringle eşitliğini kontrol ettirirsek ne olur ?


    Kod:
      String isim = "acemi";
            String yeni = "hacker";
            String birlesim = isim + yeni;
    
            String ikinciIsim = "acemihacker";
    
    
            System.out.println(birlesim == ikinciIsim ? true : false);
    Bu kodun çıktısı da "false" olacaktır. Sebebi ise String nesneler "immutable" dır. Yani "değiştirilemez". Yani bir string oluşturup bir değer verdikten sonra string değerini değiştirmeye çalıştığımızda yeni bir string nesnesi oluşturulup yeni değer bu nesneye verilir ve adres bilgisi değişmiş olur.
    Bir örnek daha yapalım :
    Kod:
       String isim = ",acemi";
            isim += "hacker";
            String ikinciIsim = "acemihacker";
    
            System.out.println(isim == ikinciIsim ? true : false);
    Burada da cevap "false" olacaktır. Aynı nesneye ekleme yapılıyor olsa dahi + operatörü arkaplanda JVM optimizasyonunda StringBuilder sınıfı ile yeni bir string oluşturacak şekilde optimize edilir ve yeni bir string adresi döndürülür.


    Bu konuda geçenleri özetlersem, == operatörü adres kontrolü yapar equalsIgnoreCase içerik kontrolü, new String()dediğimizde belleğin Heap bölgesinde oluşur, = "" dediğimizde heap içerisindeki String Pool alanında, stringler immutable nesnelerdir += işlemi stringlerde concating işlemini arkaplanda StringBuilder ile yapar bu sebeple string adresi değişir.
    Faydalı olacağını düşündüğüm bir yazının daha sonuna geldik. Umarım herkes yararlanabilir.


    ALINTIDIR!



     
    KocaReis bunu beğendi.
  2. KocaReis

    KocaReis ϜϓſϞ Site Yetkilisi Moderator

    Mesaj:
    832
    Beğeniler:
    691
    Cinsiyet:
    Erkek
    Otomatiğe almış maşallah eline sağlık. :)
     
    acemihacker bunu beğendi.
  3. acemihacker

    acemihacker Ötüken Yolcusu Bronz Üye

    Mesaj:
    205
    Beğeniler:
    74
    Cinsiyet:
    Erkek
    Hocam baya zorlandım konuyu düzenlerken adam hep kendi ismini yazmış kodlara 8-9 dk uğraştım :D
     
    KocaReis bunu beğendi.
Yükleniyor...

Bu Sayfayı Paylaş