x-kom hosting

[java]operator porównania

lightinside
utworzono
utworzono
 
 
public class Porownaj {
 
public static void main(String[] args) {
String s1 = "Pietruszka";
String s2 = "Pietr" + "uszka";
String s3 = "Pietr";
String s4 = "pietruszka";
s3 += "uszka";
System.out.println("Czy " + s1 + " = " + s2 + " ? "
+ (s1 == s2 ? "tak" : "nie"));
// składnia operatora trójargumentowego ?:
// warunek?wart1:wart2 - obliczany jest warunek MUSI ! zwrócić
// wartość logiczną, jeśli zwróci true to obliczane jest wart1,
// jesli zwróci false obliczane jest wart2
System.out.println("Czy " + s1 + " = " + s3 + " ? "
+ (s1 == s3 ? "tak" : "nie"));
System.out.println("Czy " + s1 + " = " + s4 + " ? "
+ (s1 == s4 ? "tak" : "nie"));
}
}
 
 

Dlaczego jeśli do ciągu liter dodamy inny ciąg i wychodzi nam niby taki  sam, to java mówi co innego?

 

Chodzi mi o s3, to jest jakiś znak końca lini czy czego? czym się s3 różni od s1?

rafalluz
komentarz
komentarz

Żeby porównywać stringi znak po znaku, użyj funkcji equals

 

np. s1.equals(s3)

 

s1 == s3 sprawdza, czy s1 i s3 są tym samym obiektem w pamięci (tzw. porównanie referencji), equals() sprawdza zawartość stringów zgodnie z oczekiwaniem.

lightinside
komentarz
komentarz

Ale s2 nie jest dokładnie tym samym co s1 a pokazuje że jest takie samo... -_- To jest to samo w pamięci??? Przecież to dwie inne zmienne... fakt z tym samym ale inne...

sigmaPi
komentarz
komentarz

Obiekty klasy String są niezmienne. Pozwala to na współużytkowanie adresu przez wiele zmiennych dopóty, dopóki ich wartość jest taka sama. Gdy zmienisz w obiekcie klasy String literę, tak naprawdę tworzysz nowy obiekt o innym adresie w pamięci.

 

Na przykład (adresy wyssane z palca):

String s1 = "Pietruszka";                       // s1->0001
String s2 = "Pietruszka";                       // s2->0001
System.out.println(s1 == s2 ? "Tak!" : "Nie!"); // 0001 == 0001? Tak!
s1 = "Bietruszka";                              // s1->0025
System.out.println(s1 == s2 ? "Tak!" : "Nie!"); // 0025 == 0001? Nie!

Można wymusić użycie innych adresów poprzez użycie konstruktora obiektu klasy String:

String s1 = new String("Pietruszka");           // s1 ->0050
String s2 = new String("Pietruszka");           // s2 ->0032
System.out.println(s1 == s2 ? "Tak!" : "Nie!"); // 0050 == 0032? Nie!

Natomiast equals:

String s1 = "Pietruszka";
String s2 = "Pietruszka";
System.out.println(s1.equals(s2));
// Prawda, bo:
//('P','i','e','t','r','u','s','z','k','a') == ('P','i','e','t','r','u','s','z','k','a')
String s1 = new String("Pietruszka");
String s2 = new String("Pietruszka");
System.out.println(s1.equals(s2));
// Prawda, bo:
//('P','i','e','t','r','u','s','z','k','a') == ('P','i','e','t','r','u','s','z','k','a')
rafalluz
komentarz
komentarz (edytowane)

Ale s2 nie jest dokładnie tym samym co s1 a pokazuje że jest takie samo... -_- To jest to samo w pamięci??? Przecież to dwie inne zmienne... fakt z tym samym ale inne...

 

Stałe dosłowne są traktowane jako ten sam obiekt, jeżeli stringi są identyczne.

 

Rzecz w tym, że inne nazwy zmiennych wcale nie oznaczają, że odnoszą się one do różnych obiektów. Tak było w C/C++ ze wskaźnikami, tak jest w Javie/C# z referencjami. Tak samo operator = dla typów referencyjnych domyślnie nie tworzy kopii obiektu, tylko ustawia referencję na już istniejący obiekt (albo nulla). Jest to ważne dla garbage collectora (kwestie alokacji pamięci).

 

Przykład

String s1 = "dupa";
String s2 = s1;

s2 odnosi się dokładnie do tego samego miejsca w pamięci, co s1, nie ma dwóch stringów "dupa" w pamięci, jest jeden, utworzony przy przypisaniu s1, a przypisanie s2 jedynie mówi, żeby s2 wskazywało na to samo miejsce w pamięci, co s1.

 

Gdyby przypisać s2 = "dupa" zamiast s2 = s1, stałoby się dokładnie to samo.

 

Dla odmiany na intach:

int x = 2
int y = 2

Byłyby dwa różne miejsca w pamięci zawierające wartość 2, ale porównanie == oczywiście zwróciłoby true. Jest to kwestia innej semantyki związanej z innym typem.

 

http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html

 

Jest to cholernie ważna rzecz do zrozumienia, jeśli chce się programować na poważnie - jedno z najbardziej podstawowych pytań na niemal każdej rozmowie kwalifikacyjnej.

lightinside
komentarz
komentarz

Dziękuje, już rozumiem.

 

Czyli jakbyśmy w c++ zrobili  to samo czyli dali przykładowwo

 

 
string a="awesome";
string b="awesome";
 
 

 

To mamy jeden obiekt na który wskazują dwie nazwy tak?

  • 2 miesiące później...
vzx
komentarz
komentarz

Dziękuje, już rozumiem.

 

Czyli jakbyśmy w c++ zrobili  to samo czyli dali przykładowwo

 
string a="awesome";
string b="awesome";
 
 

 

To mamy jeden obiekt na który wskazują dwie nazwy tak?

Myślę, że to zależy od implementacji kompilatora.

Wciąż szukasz rozwiązania problemu? Napisz teraz na forum!

Możesz zadać pytanie bez konieczności rejestracji - wystarczy, że wypełnisz formularz.

×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Strona wykorzystuje pliki cookies w celu prawidłowego świadczenia usług i wygody użytkowników. Warunki przechowywania i dostępu do plików cookies możesz zmienić w ustawieniach przeglądarki.