String Pool

W poprzedniej lekcji na temat porównań wspomniałem, że porównania Stringów też należą do wyjątkowego przypadku. I właśnie o tym sobie powiemy w tej lekcji. 😉

Porównujmy!

Rozpocznijmy od przeanalizowania przykładu, a później do małej refleksji nad nim.

Na początku stwórzmy kilka Stringów, pierwszy przy użyciu cudzysłowów – czyli jak zwykle:

String pablo = "pablo";

Przy użyciu operator new – w końcu String jest obiektem i ma konstruktor:

String drugiPablo = new String("pablo");

No i jeszcze jakiegoś jednego:

String trzeciPablo = "pablo";

No i może jeszcze takiego:

String czwartyPablo = new String("pablo");

Jak zdążyłeś zauważyć wszystkie wartości są takie same – ciekawe czy wszystkie porównania zwrócą prawdę. 😉

Porównajmy sobie Stringi:

if (pablo == trzeciPablo) {
    System.out.println("Pablo równa się trzeciPablo");
} else {
    System.out.println("Pablo nie równa się trzeciPablo");
}

I jeszcze w taki sposób:

if (pablo == drugiPablo) {
    System.out.println("Pablo równa sie drugipablo(1)");
} else {
    System.out.println("Pablo nie równa się drugiPablo(1)");
}

I jeszcze takie porównanie:

if (pablo.equals(drugiPablo)) {
    System.out.println("Pablo równa sie drugipablo(2)");
} else {
    System.out.println("Pablo nie równa sie drugipablo(2)");
}

I już ostatnie:

if (drugiPablo == czwartyPablo) {
    System.out.println("drugiPablo równa sie czwartyPablo");
} else {
    System.out.println("drugiPablo nie równa się czwartyPablo");
}

No i mamy cztery porównania – uruchommy program:

Zastanówmy się…

Po uruchomieniu programu otrzymaliśmy coś takiego:

Pablo równa się trzeciPablo
Pablo nie równa się drugiPablo(1)
Pablo równa sie drugipablo(2)
drugiPablo nie równa się czwartyPablo

Przeanalizujmy każdego porównanie.

Pierwsze porównanie pablo == trzeciPablo zwróciło prawdę – dlaczego?

Oba Stringi są niby takie same, ale w końcu to obiekty – a ich adresy są różne, to dlaczego otrzymaliśmy prawdę?

Prawda została zwrócona, ponieważ oba obiekty tak naprawdę są w String Pool – więc mają ten sam adres, ale jak to?

Każdy String utworzony przy użyciu cudzysłowów jest wrzucany do tak zwanego String Poola – jeżeli, więc dwa Stringi mają te samą wartość i zostały utworzony przy użycu cudzysłowów to oznacza, że ich adres jest taki sam. Po przeanalizowaniu wszystkich przykładów wrócę do głębszego omówienia String Poola.

Kolejne porównanie pablo == drugiPablo zwróciło już fałsz – dlaczego?

Jak wiesz obiekt pablo leży już w String Pool – zaś obiekt drugiPablo został utworzony przy użyciu operatora new dlatego nie został wrzucony do String Poola. Wniosek jest taki, że oba obiekty mają inne adresy, więc porównanie == zwraca fałsz.

Następne porównanie to pablo.equals(drugiPablo)), który oczywiście zwraca prawdę – używamy na obiekcie metody equals, która jak wspomniałem w poprzedniej lekcji sprawdza zawartość obiektu, a nie tylko jego adres!

Ostatnie porównanie to: drugiPablo == czwartyPablo – i oczywiście zwróciło fałsz. Dlaczego?

Oba obiekty zostały utworzone przy użyciu operatora new – w takim razie żaden z nich nie jest w String Pool. W takim razie mają one inne adresy – tak jakbyśmy tworzyli zwykłe obiekty.

Omówiliśmy już porównania – zagłębmy się teraz w ten cały String Pool.

Czym jest dokładnie String Pool…

String Pool to taki obszar w pamięci, do którego są wrzucane Stringi utworzone przy użyciu cudzysłowów. No tak tyle już wiesz z akapitu wyżej. No to mówię więcej.

Podczas wrzucania Stringa do String Poola najpierw jest sprawdzane czy w całym String Pool istnieje String o dokładnie takiej wartości. Jeżeli istnieje to zwracany jest adres już tego istniejącego Stringa w String Pool.

Wnioski są proste – w String Pool znajdują się tylko Stringi utworzone przy użyciu cudzysłowów np. String name = “pablo” – i Stringi mieszczące się w nim się nie potwarzają! Jeżeli jakiś nowy String się powtarza to zwracany jest adres już tego istniejącego!

Po co?

String Pool został wprowadzony w celu optymalizacji Javy – znaki mają to do siebie, że zajmują sporo miejsca. Dlatego, aby zmniejszyć ilość zajmowanego miejsca został stworzony String Pool, który nie przechowuje duplikatów – dzięki temu wirtualna maszyna Javy zużywa mniej pamięci. 😉

Podsumowanie

Podsumowując, Stringi najlepiej jest tworzyć przy użyciu cudzysłowiów – wtedy utworzone obiekty będą trafiać do String Pool i nie będą niepotrzebnie zajmowały miejsca.

Każde porównanie Stringa wykonuj przy użyciu metody equals – operator == nie zawsze Ci pomoże!

Aby mieć pewność, że rozumiesz całe zagadnienie odpowiedz w komentarzu na pytanie, które porównanie zwróci true, a które false – każdą odpowiedź uzasadnij dlaczego. 😉

public class Main {

    public static void main(String[] args) {
      String john = "john";
      String johny = "johny";
      String newJohn = new String("john");
      String nextJohny = new String("johny");
      String nextJohn = new String("john");
      String oldJohn = john;
      String amy = "amy";
      String nextAmy = new String("amy");

        System.out.println("1." + (john == johny));
        System.out.println("2." + (nextJohny == johny));
        System.out.println("3." + (john == nextJohn));
        System.out.println("4." + newJohn.equals(john));
        System.out.println("5." + (oldJohn == john));
        System.out.println("6." + (amy == nextAmy));
        System.out.println("7." + amy.equals(nextAmy));
    }
}

Przypominam, że na odpowiedzi czekam w komentarzach. 😉

 

Kamil Klimek

Od 2016 jestem programistą Java. Przez pierwsze 4 lata pracowałem jako Full Stack Java Developer. Później postanowiłem postawić nacisk na Javę, żeby jeszcze lepiej ją poznać.

Subscribe
Powiadom o
guest
7 komentarzy
najstarszy
najnowszy oceniany
Inline Feedbacks
View all comments
Agata
Agata
5 lat temu

1. false
2. false
3. false
4. true
5. true
6. false
7. true

Łatwe 🙂

Agata
Agata
5 lat temu
Reply to  Agata

PS. Jak wchodzę przez link: https://1024kb.pl/category/kurs-java-od-podstaw/tydzien-3/ to nie widać wszystkich tematów tylko jeden: “Zabezpieczony: Aplikacja domowa – zadanie”

SO EK
SO EK
5 lat temu
Reply to  Agata

Wejdź przez link z maila.

Agata
Agata
5 lat temu
Reply to  SO EK

Dobra ale nie chcę za każdym razem wchodzić na maila, żeby się dostać do kursu

Kamil Klimek
Kamil Klimek
5 lat temu
Reply to  Agata

Niestety dostęp do kursu jest zablokowany hasłem i każda publikacja lekcji pokazywałaby się na stronie głównej, której nie chce zaśmiecać lekcjami. Dlatego widoczność lekcji jest zablokowana z poziomu strony głównej i kategorii.

Aby mieć dostęp do kursu wystarczy dodać do zakładek przeglądarki stronę https://1024kb.pl/kurs-java-od-podstaw/ aby widzieć zbiór wszystkich lekcji. 😉

SO EK
SO EK
5 lat temu

1. fałsz
2. fałsz
3. fałsz
4. prawda
5. prawda
6. fałsz
7. prawda

Poul
Poul
5 lat temu

1. false – mają różną wartość, zatem nie są duplikatami, nie trafiają do String pool więc mają inne adresy w pamięci
2. false – nextJohny jest twórzony jako nowy obiekt, więc ma swój adres, inny niź johny
3. false – to samo co powyżej
4. true – porównywana jest wartość Stringów, więc są równe
5. true – do oldJohn został przypisany jest adres john, więc są równe
6. false – to samo co w przykładzie drugim
7. true – to samo co w przykładzie czwartym

7
0
Would love your thoughts, please comment.x