web-dev-qa-db-ja.com

文字列内の特定のインデックスにある文字を置き換える

文字列内の特定のインデックスにある文字を置き換えようとしています。

私がやっているのは:

String myName = "domanokz";
myName.charAt(4) = 'x';

これはエラーになります。これを行う方法はありますか?

334
dpp

文字列は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);
505
Petar Ivanov

文字列をchar []に変換し、文字をインデックスに置き換えてから、配列を文字列に変換します。

String myName = "domanokz";
char[] myNameChars = myName.toCharArray();
myNameChars[4] = 'x';
myName = String.valueOf(myNameChars);
134
16dots

文字列はJavaの不変クラスで、それを変更するように見えるメソッドは常に変更を加えた新しい文字列オブジェクトを返します。文字列を操作したい場合は、スレッドセーフを必要とする場合にStringBuilderまたはStringBufferを検討してください。

17
no name

私は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);       
}
11

ここで先に答えたように、Stringインスタンスは 不変 です。 StringBufferStringBuilderは変更可能で、スレッドセーフである必要があるかどうかにかかわらず、そのような目的に適しています。

しかし、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();
    }
}
5
C.Champagne

次のように文字列を上書きすることができます。

String myName = "halftime";
myName = myName.substring(0,4)+'x'+myName.substring(5);  

文字列myNameは両方の行と、2行目の両側にあることに注意してください。

したがって、文字列が技術的に不変であっても、実際には、それらを上書きすることで編集可能として扱うことができます。

4
CodeMed

最初に気づいたことは、charAtはメソッドであり、等号を使って値を代入しても何もしないことです。文字列が不変の場合、文字列オブジェクトを変更するためのcharAtメソッドは、新しい文字を含む引数を受け取る必要があります。残念ながら、文字列は不変です。文字列を変更するには、Petar Ivanov氏が提案したようにStringBuilderを使用する必要がありました。

0
dpp