lightinside utworzono 21 maja 2014 utworzono 21 maja 2014 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 21 maja 2014 komentarz 21 maja 2014 Ż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 21 maja 2014 Autor komentarz 21 maja 2014 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 22 maja 2014 komentarz 22 maja 2014 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 22 maja 2014 komentarz 22 maja 2014 (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 23 maja 2014 Autor komentarz 23 maja 2014 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?
vzx komentarz 28 lipca 2014 komentarz 28 lipca 2014 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.