Wykorzystanie String poola

0

Testuję sobie String poola na takim kodzie obecnie:

String abc = "abc";
String zm1 = "abc" + "d";
String zm2 = abc + "d";     
String zm3 = "abcd";
String zm4 = new String("abcd");
String zm5 = new String(zm3);
 
String aaa = abc + "d";
 
System.out.println("zm1 == zm2 : " + (zm1 == zm2) );
System.out.println("zm1 == zm3 : " + (zm1 == zm3) );
System.out.println("zm1 == zm4 : " + (zm1 == zm4) );
System.out.println("zm2 == zm3 : " + (zm2 == zm3) );
System.out.println("zm2 == zm4 : " + (zm2 == zm4) );
System.out.println("zm3 == zm4 : " + (zm3 == zm4) );
System.out.println("zm3 == zm5 : " + (zm3 == zm5) );
System.out.println("zm3 == zm5 : " + (zm4 == zm5) );
 
System.out.println("zm2 == aaa : " + (zm2 == aaa) );

Z takim wynikiem :

zm1 == zm2 : false
zm1 == zm3 : true
zm1 == zm4 : false
zm2 == zm3 : false
zm2 == zm4 : false
zm3 == zm4 : false
zm3 == zm5 : false
zm3 == zm5 : false
 
zm2 == aaa : false

Nie rozumiem czemu tylko w przypadkuzm1 == zm3 otrzymuję true, tylko w tym przykładzie działa String pool? Czemu np. w przypadkuzm2 == zm3 wyrzuca mi ```
false


Trochę szukałem w sieci [tutaj](http://javastart.pl/static/klasy/string-stringbuffer-i-stringbuilder/) i wiem, że zapis ```
String zm1 = "abc" + "d";
``` da mi zapis ```
String zm1 = new StringBuilder(abc).append("d").toString();
``` Ale dalej nie rozumiem czemu mam tyle wyników ```
false
```.
0

A jak Dasz tak:

System.out.println("zm1 == zm2 : " + (zm1.equals(zm2))) ;

to Dostaniesz true. '==' porównuje referencje, a equals wartość. Dalej nie sprawdzam, Idź tym tropem; więcej tutaj:
http://web.mit.edu/6.005/www/fa15/classes/15-equality/

0
lion137 napisał(a):

A jak Dasz tak:

System.out.println("zm1 == zm2 : " + (zm1.equals(zm2))) ;

to Dostaniesz true. '==' porównuje referencje, a equals wartość. Dalej nie sprawdzam, Idź tym tropem; więcej tutaj:
http://web.mit.edu/6.005/www/fa15/classes/15-equality/

Jasne, że masz rację i można zrobić to poprawnie poprzez ```
equals

0

" Jasne, że masz rację i można zrobić to poprawnie poprzez equals"
Wszystko tutaj jest poprawnie, po prostu '==' informuje, że podane mu operandy są dwoma różnymi wskaźnikami i nie interesuje go na co one wskazują.

0
lion137 napisał(a):

" Jasne, że masz rację i można zrobić to poprawnie poprzez equals"
Wszystko tutaj jest poprawnie, po prostu '==' informuje, że podane mu operandy są dwoma różnymi wskaźnikami i nie interesuje go na co one wskazują.

Chodzi o to, że moim zdaniem powinny te porównania w większości być takimi samymi wskaźnikami (pary). Np tutaj po mimo użycia

==

mam same wartości

true
				String zmienna1 = "a";
				String zmienna2 = "b";
				String zmienna3 = "c";
				String zmienna4 = "d";
				String zmienna5 = "e";
				String zmienna6 = "e";
				String zmienna7 = "d";
				String zmienna8 = "c";
				String zmienna9 = "b";
				String zmienna10 = "a";
				
				System.out.println(zmienna1 == zmienna10);
				System.out.println(zmienna2 == zmienna9);
				System.out.println(zmienna3 == zmienna8);
				System.out.println(zmienna4 == zmienna7);
				System.out.println(zmienna5 == zmienna6);

Nie rozumiem czemu te pary z pierwszego postu nie trafiają prawdopodobnie do String poola.

Z jakiegoś powodu to:

		String abc = "abc";
		String zm2 = abc + "d";     
		String zm3 = "abcd";
		System.out.println(zm2 == zm3);

zwraca mi false, a moim zdaniem powinno być true.

0

Sam sobie już Odpowiedziałeś na to pytanie, jeśli string trafia do String Pool, czyli w przypadku jak jest:

String x="Foo";
String y="Foo";
if(x==y) // --> true

to JVM wyciąga go i nadaje mu tę samą referencję, jak znajdzie pasującą nazwę. Natomiast gdy włącza się operator new:

String x="Foo";
String y=new String("Foo"); // lub new StringBuilder(...)
if (x==y) // --> false

rezerwowane jest na stosie miejsce na nowy String i tworzy się do nie go nowa referencja; i, podczas, gdy x jest w String Pool, to y jest gdzie indziej i JVM nie znajduje nic pasującego do x w Pool - u i zwraca false.

0
lion137 napisał(a):

Sam sobie już Odpowiedziałeś na to pytanie, jeśli string trafia do String Pool, czyli w przypadku jak jest:

String x="Foo";
String y="Foo";
if(x==y) // --> true

to JVM wyciąga go i nadaje mu tę samą referencję, jak znajdzie pasującą nazwę. Natomiast gdy włącza się operator new:

String x="Foo";
String y=new String("Foo"); // lub new StringBuilder(...)
if (x==y) // --> false

rezerwowane jest na stosie miejsce na nowy String i tworzy się do nie go nowa referencja; i, podczas, gdy x jest w String Pool, to y jest gdzie indziej i JVM nie znajduje nic pasującego do x w Pool - u i zwraca false.

Rozumiem to co napisałeś ale wydaje mi się, że to wygląda trochę inaczej.
Kiedy używam operatora new to rzeczywiście robię nowy obiekt w innym miejscu (innym niż String pool), ale przy takim tworzeniu obiektu automatycznie nowy literał trafia do String poola - z tego powodu oczekuję, że będzie w tym samym miejscu.

I drugi przypadek gdzie moim zdaniem też literał jest ten sam, w tym samym miejscu:

		String abc = "abc";
		String zm2 = abc + "d";   
		String zm3 = "abcd";
		System.out.println(zm2 == zm3);

Zdaję sobie sprawę, że kryje się pod tym

String zm2 = new StringBuilder(abc).append("d").toString();

Ale tak jak w przykładzie wyżej myślę, że ten sam literał znajduje się w tym samym miejscu.

Może coś źle gdzieś przeczytałem ale już w kilku miejscach znalazłem informację o tym, że z operatorem new wiąże się powstanie dwóch obiektów - osobny obiekt i ten związany z String poolem.

0

Wydaje mi sie, że za bardzo Kombinujesz, JVM jakos sobie zarządza Stringami (to w końcu spora częśc każdego programu); ja tak nie rozkminiam, po prostu jak chcę porównać wartość to używam equals, a jak sprawdzić referencję to '==' i tyle.

1 użytkowników online, w tym zalogowanych: 0, gości: 1