Zdaję sobie sprawę z tego, że odpowiedziano na śmierć, ale warto zauważyć, że nigdy nie wolno przypisywać wyniku wywołania funkcji w java. Nie ma takich rzeczy jak odwołania do C (?) I C ++.
ApproachingDarknessFish
1
@ValekHalfHeart w VB, używasz nawiasów, aby uzyskać dostęp do indeksu tablicy, co może być powodem, że jestem zdezorientowany, kiedy zaczynałem w Javie: D
dpp
@ApproachingDarknessFish Nie jestem pewien, co masz na myśli, mówiąc, że „nigdy nie wolno przypisywać wyniku wywołania funkcji w java”. Na pewno dasz radę double r = Math.sin(3.14)? Jak to się ma do tego pytania? Dzięki.
flow2k
1
@ flow2k Och Jezu, stary komentarz, więc nie można edytować, ale to literówka, należy powiedzieć, że „nigdy nie wolno przypisać do wyniku wywołania funkcji w Javie”. Czyli możesz napisać „foo = bar ();” ale nigdy „bar () = foo;”.
ApproachingDarknessFish
Dzięki za wyjaśnienie @ApproachingDarknessFish. Myślę, że byłoby dziwnie przypisać coś do wyniku funkcji - czy istnieją języki, które na to pozwalają? Zastanawiam się, jaki byłby przypadek użycia.
flow2k
Odpowiedzi:
566
Ciągi są niezmienne w Javie. Nie możesz ich zmienić.
Ach, masz na myśli replacemetodę, która nie zmodyfikuje ciągu, ale zwróci tylko nowy ciąg?
dpp,
1
To trochę skomplikowane, panie Petar. Czy to najlepszy sposób, aby to zrobić? Ach, słyszałem wcześniej o StringBuilder, czy to coś zmienia? Czy da mi to łatwiejszą metodę?
dpp,
158
Zamień ciąg znaków na char [], zamień literę na indeks, a następnie przekonwertuj tablicę z powrotem na ciąg znaków.
Uwielbiam to rozwiązanie. Skończyło się na zmianie trzeciego wiersza na myNameChars [index] = character.toCharArray () [0]; dla uproszczenia. Niezłe rozwiązanie.
Dale
2
wygląda znacznie lepiej niż drugi brzydszymyName.substring(0,4)+'x'+myName.substring(5);
user924
To jest o wiele prostsze
Shiva Acharjee
19
Stringto niezmienna klasa w java. Każda metoda, która wydaje się ją modyfikować, zawsze zwraca nowy obiekt łańcucha z modyfikacją.
Jeśli chcesz manipulować ciągiem, rozważ StringBuilderlub StringBufferw przypadku, gdy potrzebujesz bezpieczeństwa wątku.
Jak już tu wcześniej odpowiedziano, Stringinstancje są niezmienne . StringBufferi StringBuildermożna je modyfikować i nadają się do tego celu, niezależnie od tego, czy chcesz być bezpieczny dla wątków, czy nie.
Istnieje jednak sposób na zmodyfikowanie ciągu, ale nigdy nie poleciłbym go, ponieważ jest on niebezpieczny, zawodny i można go uznać za oszustwo: można użyć odbicia do zmodyfikowania wewnętrznej chartablicy zawierającej obiekt String. Odbicie pozwala na dostęp do pól i metod, które zwykle są ukryte w bieżącym zakresie (metody prywatne lub pola z innej klasy ...).
publicstaticvoid main(String[] args){String text ="This is a test";try{//String.value is the array of char (char[])//that contains the text of the StringField valueField =String.class.getDeclaredField("value");//String.value is a private variable so it must be set as accessible //to read and/or to modify its value
valueField.setAccessible(true);//now we get the array the String instance is actually usingchar[] value =(char[])valueField.get(text);//The 13rd character is the "s" of the word "Test"
value[12]='x';//We display the string which should be "This is a text"System.out.println(text);}catch(NoSuchFieldException|SecurityException e){
e.printStackTrace();}catch(IllegalArgumentException e){
e.printStackTrace();}catch(IllegalAccessException e){
e.printStackTrace();}}
Nie doceniłem twojej odpowiedzi, ale muszę przyznać, że mam problem z terminem „nadpisuj” (choć myślę, że zgadzamy się z tą koncepcją). Sam obiekt pozostaje niezmieniony. Po prostu spraw, aby zmienna odwoływała się do innego obiektu. Przy okazji warto wspomnieć, że w swoim przykładzie tworzysz co najmniej cztery instancje String.
C.Champagne
0
Pierwszą rzeczą, którą powinienem zauważyć, charAtjest metoda i przypisanie jej wartości za pomocą znaku równości nic nie da. Jeśli ciąg jest niezmienny, charAtmetoda, aby dokonać zmiany w obiekcie ciągu, musi otrzymać argument zawierający nowy znak. Niestety, ciąg jest niezmienny. Aby zmodyfikować ciąg, musiałem użyć StringBuilder zgodnie z sugestią pana Petara Iwanowa.
double r = Math.sin(3.14)
? Jak to się ma do tego pytania? Dzięki.Odpowiedzi:
Ciągi są niezmienne w Javie. Nie możesz ich zmienić.
Musisz utworzyć nowy ciąg z zastąpionym znakiem.
Lub możesz użyć StringBuilder:
źródło
replace
metodę, która nie zmodyfikuje ciągu, ale zwróci tylko nowy ciąg?Zamień ciąg znaków na char [], zamień literę na indeks, a następnie przekonwertuj tablicę z powrotem na ciąg znaków.
źródło
myName.substring(0,4)+'x'+myName.substring(5);
String
to niezmienna klasa w java. Każda metoda, która wydaje się ją modyfikować, zawsze zwraca nowy obiekt łańcucha z modyfikacją.Jeśli chcesz manipulować ciągiem, rozważ
StringBuilder
lubStringBuffer
w przypadku, gdy potrzebujesz bezpieczeństwa wątku.źródło
Zgadzam się z Petarem Iwanowem, ale najlepiej wdrożyć w następujący sposób:
źródło
Jak już tu wcześniej odpowiedziano,
String
instancje są niezmienne .StringBuffer
iStringBuilder
można je modyfikować i nadają się do tego celu, niezależnie od tego, czy chcesz być bezpieczny dla wątków, czy nie.Istnieje jednak sposób na zmodyfikowanie ciągu, ale nigdy nie poleciłbym go, ponieważ jest on niebezpieczny, zawodny i można go uznać za oszustwo: można użyć odbicia do zmodyfikowania wewnętrznej
char
tablicy zawierającej obiekt String. Odbicie pozwala na dostęp do pól i metod, które zwykle są ukryte w bieżącym zakresie (metody prywatne lub pola z innej klasy ...).źródło
Możesz zastąpić ciąg w następujący sposób:
Zauważ, że ciąg
myName
występuje w obu liniach i po obu stronach drugiej linii.Dlatego, mimo że ciągi technicznie mogą być niezmienne, w praktyce można je traktować jako edytowalne, zastępując je.
źródło
Pierwszą rzeczą, którą powinienem zauważyć,
charAt
jest metoda i przypisanie jej wartości za pomocą znaku równości nic nie da. Jeśli ciąg jest niezmienny,charAt
metoda, aby dokonać zmiany w obiekcie ciągu, musi otrzymać argument zawierający nowy znak. Niestety, ciąg jest niezmienny. Aby zmodyfikować ciąg, musiałem użyć StringBuilder zgodnie z sugestią pana Petara Iwanowa.źródło
to zadziała
Wyjście: domaxokz
źródło
myName.replace(myName.charAt(5),'x')
da cidxmanxkz
, co prawdopodobnie nie jest wymagane.