Według String # intern () , intern
metoda ma powrócić String z puli String Jeśli łańcuch znajduje się w basenie String, w przeciwnym razie nowy obiekt zostanie dodany ciąg w puli ciąg i odniesienie ten ciąg jest zwracany.
Więc próbowałem tego:
String s1 = "Rakesh";
String s2 = "Rakesh";
String s3 = "Rakesh".intern();
if ( s1 == s2 ){
System.out.println("s1 and s2 are same"); // 1.
}
if ( s1 == s3 ){
System.out.println("s1 and s3 are same" ); // 2.
}
Spodziewałem się, że s1 and s3 are same
zostanie wydrukowany, ponieważ s3 jest internowany i s1 and s2 are same
nie zostanie wydrukowany. Ale wynik jest taki: obie linie są drukowane. Oznacza to, że domyślnie stałe String są internowane. Ale jeśli tak, to dlaczego potrzebujemy tej intern
metody? Innymi słowy, kiedy powinniśmy skorzystać z tej metody?
java
string
string-interning
Rakesh Juyal
źródło
źródło
intern
taką metodę publiczną? Czy nie powinniśmy stosowaćintern
metody prywatnej, aby nikt nie miał do niej dostępu? Czy jest jakiś cel tej metody?Odpowiedzi:
Java automatycznie internalizuje literały łańcuchowe. Oznacza to, że w wielu przypadkach operator == działa na ciągi w taki sam sposób, jak działa na ints lub innych pierwotnych wartościach.
Ponieważ internalizacja jest automatyczna dla literałów łańcuchowych,
intern()
metodę należy stosować na łańcuchach zbudowanych znew String()
Na twoim przykładzie:
wróci:
We wszystkich przypadkach oprócz
s4
zmiennej wartość, dla której wyraźnie utworzono za pomocąnew
operatora, a dla której wynikuintern
nie użyto metody, jest to pojedyncza niezmienna instancja, która jest zwracana stała pula ciągów JVM .Aby uzyskać więcej informacji, zobacz JavaTechniques „String Equality and Interning” .
źródło
String s1 = "Rakesh";
pierwszy OB1String s4 = new String("Rakesh");
Drugi OB2 Tak więc reszta (s2, s3, s5) odwołuje się do tego samego obiektu (OB1) utworzonego w „pula ciągów”. Więc mogę powiedzieć, że ta.intern()
metoda zastosowana do zapobiegania tworzeniu nowego obiektu jest dostępna, jeśli ten sam ciąg znaków jest dostępny wstring pool
If moje założenie jest błędne, więc daj mi kierunek.W ostatnim projekcie skonfigurowano niektóre ogromne struktury danych z danymi odczytanymi z bazy danych (a zatem nie ze stałymi / literałami ciągów), ale z dużą ilością powielania. Była to aplikacja bankowa, a takie rzeczy jak nazwy skromnego zestawu (może 100 lub 200) korporacji pojawiły się wszędzie. Struktury danych były już duże i gdyby wszystkie te nazwy korpusów były unikatowymi obiektami, przepełniłyby pamięć. Zamiast tego wszystkie struktury danych zawierały odniesienia do tych samych 100 lub 200 obiektów String, co oszczędza dużo miejsca.
Kolejną niewielką zaletą internowanych ciągów jest to, że
==
można (z powodzeniem!) Porównać ciągi, jeśli wszystkie zaangażowane ciągi mają gwarancję internowania. Oprócz uproszczonej składni jest to również poprawa wydajności. Ale jak zauważyli inni, zrobienie tego wiąże się z dużym ryzykiem wprowadzenia błędów programistycznych, dlatego powinno się to robić jedynie jako desperacki środek w ostateczności.Minusem jest to, że internowanie ciągu zajmuje więcej czasu niż zwykłe wyrzucenie go na stos, i że przestrzeń dla internowanych ciągów może być ograniczona, w zależności od implementacji Java. Najlepiej zrobić to, gdy masz do czynienia ze znaną rozsądną liczbą ciągów z wieloma duplikacjami.
źródło
The downside is that interning a String takes more time than simply throwing it on the heap, and that the space for interned Strings may be limited
nawet jeśli nie użyjesz metody intern dla stałej String, zostanie internowana automatycznie.==
na łańcuchy.Chcę dodać moje 2 centy za używanie
==
z internowanymi łańcuchami.Pierwszą rzeczą
String.equals
jestthis==object
.Więc chociaż istnieje niewielki wzrost wydajności (nie wywołujesz metody), z punktu widzenia opiekuna używanie
==
jest koszmarem, ponieważ niektóre internowane łańcuchy mają tendencję do nie internowania.Dlatego sugeruję, aby nie polegać na specjalnym przypadku
==
internowanych łańcuchów, ale zawsze używajequals
zgodnie z zamierzeniami Goslinga.EDYCJA: internowany staje się internowany:
W wersji 2.0 opiekun postanowił
hasReferenceVal
upublicznić, nie wchodząc w szczegóły, że oczekuje szeregu internowanych ciągów.Teraz masz błąd, który może być bardzo trudny do znalezienia, ponieważ w większości przypadków tablica zawiera wartości dosłowne, a czasami używany jest łańcuch nieliteralny. Jeśli
equals
użyto zamiast==
wtedyhasReferenceVal
musiałby nadal kontynuować pracę. Po raz kolejny wzrost wydajności jest niewielki, ale koszty utrzymania są wysokie.źródło
Literały ciągowe i stałe są domyślnie internowane. To znaczy
"foo" == "foo"
(zadeklarowane przez literały ciągów), alenew String("foo") != new String("foo")
.źródło
intern
,String literals and constants are interned by default
:, jest poprawne.new String("foo")
-> Tutaj, jeden literał „Foo” napisany jest w puli napisów, a drugi w stercie, więc powstają łącznie 2 obiekty.Naucz się Java String Intern - raz na zawsze
Łańcuchy w Javie są niezmiennymi obiektami z założenia. Dlatego dwa obiekty łańcuchowe nawet o tej samej wartości będą domyślnie różnymi obiektami. Jeśli jednak chcemy zaoszczędzić pamięć, możemy wskazać na użycie tej samej pamięci przez koncepcję zwaną intern intern.
Poniższe zasady pomogą ci zrozumieć pojęcie w sposób jasny:
Przykład:
Uwaga: Przypadki motywacyjne dla intern stringów nie są tutaj omawiane. Jednak oszczędzanie pamięci z pewnością będzie jednym z głównych celów.
źródło
powinieneś wskazać dwa okresy, które są czasem kompilacji i czasem wykonania. na przykład:
z jednej strony, w przykładzie 1, okazuje się, że wszystkie wyniki zwracają wartość true, ponieważ w czasie kompilacji jvm umieści „test” w puli literałów, jeśli jvm znajdzie „test”, to wtedy użyje istniejącego, w przykładzie 1, łańcuchy „testowe” wskazują na ten sam adres pamięci, więc przykład 1 zwróci true. z drugiej strony w przykładzie 2 metoda substring () jest wykonywana w czasie wykonywania, w przypadku „test” == ”! test” .substring (1) pula utworzy obiekt o dwóch ciągach, „ test ”i„! test ”, więc są to różne obiekty referencyjne, więc ten przypadek zwróci false, w przypadku„ test ”==”! test ”.substring (1) .intern (), metoda intern ( ) umieści „„! test ”.substring (1)” w puli literałów,
źródło
http://en.wikipedia.org/wiki/String_interning
internowanie ciągów to metoda przechowywania tylko jednej kopii każdej odrębnej wartości ciągu, która musi być niezmienna. Wewnętrzne łańcuchy sprawiają, że niektóre zadania przetwarzania łańcucha są bardziej czasochłonne lub zajmują mało miejsca, co kosztuje więcej czasu, gdy łańcuch jest tworzony lub internowany. Różne wartości są przechowywane w wewnętrznej puli ciągów.
źródło
Internowane ciągi unikają duplikatów ciągów. Interning oszczędza pamięć RAM kosztem więcej czasu procesora na wykrycie i zastąpienie zduplikowanych ciągów. Istnieje tylko jedna kopia każdego ciągu, który został internowany, bez względu na to, ile odwołań do niego wskazuje. Ponieważ ciągi są niezmienne, jeśli dwie różne metody przypadkowo wykorzystują ten sam ciąg, mogą udostępniać kopię tego samego ciągu. Proces konwersji zduplikowanych ciągów na współdzielone nazywa się interning.String.intern () daje adres kanonicznego wzorca String. Możesz porównać internowane ciągi z prostym == (który porównuje wskaźniki) zamiast z równymktóry porównuje znaki ciągu jeden po drugim. Ponieważ ciągi są niezmienne, proces internowania pozwala na dalsze oszczędzanie miejsca, na przykład nie tworząc osobnego literału łańcuchowego dla „puli”, gdy istnieje jako podciąg innego literału, takiego jak „hipopotam”.
Aby zobaczyć więcej http://mindprod.com/jgloss/interned.html
źródło
WYNIK
źródło
Gdy dwa ciągi są tworzone niezależnie,
intern()
pozwala je porównać, a także pomaga w tworzeniu odwołania w puli ciągów, jeśli odwołanie nie istniało wcześniej.Gdy używasz
String s = new String(hi)
, Java tworzy nową instancję ciągu, ale kiedy używaszString s = "hi"
, java sprawdza, czy w kodzie jest wystąpienie słowa „cześć”, a jeśli istnieje, po prostu zwraca odwołanie.Ponieważ porównywanie ciągów jest oparte na odwołaniu,
intern()
pomaga w tworzeniu odniesienia i pozwala na porównanie zawartości ciągów.Kiedy użyjesz
intern()
w kodzie, to wyczyści miejsce używane przez ciąg znaków odnoszący się do tego samego obiektu i po prostu zwraca odwołanie do już istniejącego tego samego obiektu w pamięci.Ale w przypadku p5, gdy używasz:
Kopiowana jest tylko zawartość p3, a p5 jest nowo tworzone. Więc nie jest internowany .
Więc wynik będzie:
źródło
źródło
Metoda string intern () służy do utworzenia dokładnej kopii obiektu ciągu stosu w stałej puli ciągów. Obiekty ciągów w puli stałych ciągów są automatycznie internowane, ale obiekty ciągów w stercie nie są. Głównym zastosowaniem tworzenia stażystów jest oszczędzanie miejsca w pamięci i szybsze porównywanie obiektów łańcuchowych.
Źródło: Co to jest stażysta w java?
źródło
Jak powiedziałeś, ta
intern()
metoda ciągu najpierw znajdzie z puli String, jeśli ją znajdzie, zwróci obiekt wskazujący na nią lub doda nowy ciąg do puli.s1
Is2
są dwa obiekty wskazujące na basenie ciąg „Hello” i używając"Hello".intern()
przekonają się, żes1
is2
. Więc"s1 == s3"
zwraca prawdę, a także dos3.intern()
.źródło
Używając odwołania do obiektu sterty, jeśli chcemy uzyskać odpowiednie odniesienie do obiektu stałej puli ciągów znaków , powinniśmy skorzystać z intern ()
Widok obrazkowy
Krok 1: Obiekt z danymi „Rakesh” zostaje utworzony w puli stałej stosu i ciągu. Również s1 zawsze wskazuje na obiekt sterty.
Krok 2: Korzystając z referencji do obiektu sterty s1, staramy się uzyskać odpowiedni referencyjny obiekt puli stałej ciągu sc2 za pomocą intern ()
Krok 3: Celowe utworzenie obiektu z danymi „Rakesh” w stałej puli ciągów, do której odwołuje się nazwa s3
Jako operator „==” przeznaczony do porównania.
Pierwsze false dla s1 == s2
Pierwsze prawdziwe dla s2 s3 ==
Mam nadzieję, że to pomoże!!
źródło