Próbuję zastąpić znak w określonym indeksie w ciągu.
To co robię to:
String myName = "domanokz";
myName.charAt(4) = 'x';
To daje błąd. Czy jest na to jakaś metoda?
double r = Math.sin(3.14)
? Jak to się ma do tego pytania? Dzięki.
Próbuję zastąpić znak w określonym indeksie w ciągu.
To co robię to:
String myName = "domanokz";
myName.charAt(4) = 'x';
To daje błąd. Czy jest na to jakaś metoda?
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.
String myName = "domanokz";
String newName = myName.substring(0,4)+'x'+myName.substring(5);
Lub możesz użyć StringBuilder:
StringBuilder myName = new StringBuilder("domanokz");
myName.setCharAt(4, 'x');
System.out.println(myName);
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.
String myName = "domanokz";
char[] myNameChars = myName.toCharArray();
myNameChars[4] = 'x';
myName = String.valueOf(myNameChars);
myName.substring(0,4)+'x'+myName.substring(5);
Zgadzam się z Petarem Iwanowem, ale najlepiej wdrożyć w następujący sposób:
public String replace(String str, int index, char replace){
if(str==null){
return str;
}else if(index<0 || index>=str.length()){
return str;
}
char[] chars = str.toCharArray();
chars[index] = replace;
return String.valueOf(chars);
}
Jak już tu wcześniej odpowiedziano, String
instancje są niezmienne . StringBuffer
i StringBuilder
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 ...).
public static void main(String[] args) {
String text = "This is a test";
try {
//String.value is the array of char (char[])
//that contains the text of the String
Field 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 using
char[] 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();
}
}
Możesz zastąpić ciąg w następujący sposób:
String myName = "halftime";
myName = myName.substring(0,4)+'x'+myName.substring(5);
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.
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.
to zadziała
String myName="domanokz";
String p=myName.replace(myName.charAt(4),'x');
System.out.println(p);
Wyjście: domaxokz
myName.replace(myName.charAt(5),'x')
da ci dxmanxkz
, co prawdopodobnie nie jest wymagane.