文字列内の特定のインデックスにある文字を置き換えようとしています。
私がやっているのは:
String myName = "domanokz";
myName.charAt(4) = 'x';
これはエラーになります。これを行う方法はありますか?
文字列はJavaでは不変です。変更することはできません。
文字を置き換えて新しい文字列を作成する必要があります。
String myName = "domanokz";
String newName = myName.substring(0,4)+'x'+myName.substring(5);
あるいはStringBuilderを使うこともできます。
StringBuilder myName = new StringBuilder("domanokz");
myName.setCharAt(4, 'x');
System.out.println(myName);
文字列をchar []に変換し、文字をインデックスに置き換えてから、配列を文字列に変換します。
String myName = "domanokz";
char[] myNameChars = myName.toCharArray();
myNameChars[4] = 'x';
myName = String.valueOf(myNameChars);
文字列はJavaの不変クラスで、それを変更するように見えるメソッドは常に変更を加えた新しい文字列オブジェクトを返します。文字列を操作したい場合は、スレッドセーフを必要とする場合にStringBuilderまたはStringBufferを検討してください。
私はPetar Ivanovに同意しますが、次のように実装するのが最善です。
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);
}
ここで先に答えたように、String
インスタンスは 不変 です。 StringBuffer
とStringBuilder
は変更可能で、スレッドセーフである必要があるかどうかにかかわらず、そのような目的に適しています。
しかし、Stringを変更する方法はありますが、安全ではなく信頼性が低く、不正行為と見なすことができるため、お勧めできません。Stringオブジェクトに含まれる内側のchar
配列を変更するには reflection を使用できます。 Reflection は現在のスコープでは通常隠されているフィールドやメソッドにアクセスすることを可能にします(プライベートメソッドまたは他のクラスのフィールド...)。
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();
}
}
次のように文字列を上書きすることができます。
String myName = "halftime";
myName = myName.substring(0,4)+'x'+myName.substring(5);
文字列myName
は両方の行と、2行目の両側にあることに注意してください。
したがって、文字列が技術的に不変であっても、実際には、それらを上書きすることで編集可能として扱うことができます。
最初に気づいたことは、charAt
はメソッドであり、等号を使って値を代入しても何もしないことです。文字列が不変の場合、文字列オブジェクトを変更するためのcharAt
メソッドは、新しい文字を含む引数を受け取る必要があります。残念ながら、文字列は不変です。文字列を変更するには、Petar Ivanov氏が提案したようにStringBuilderを使用する必要がありました。