Sostituisci un carattere in un indice specifico in una stringa?


382

Sto cercando di sostituire un carattere in un indice specifico in una stringa.

Quello che sto facendo è:

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

Questo dà un errore. C'è un metodo per farlo?


12
Mi rendo conto che è stato risposto alla morte, ma vale la pena notare che non è mai possibile assegnare il risultato di una chiamata di funzione in Java. Non ci sono cose come i riferimenti di C (?) E C ++.
Avvicinamento

1
@ValekHalfHeart in VB, usi la parentesi per accedere all'indice di un array, questo potrebbe essere il motivo per cui sono confuso quando stavo iniziando in Java: D
dpp

@ApproachingDarknessFish Non sono sicuro di cosa intendi per "non è mai stato possibile assegnare il risultato di una chiamata di funzione in Java". Sicuramente puoi farlo double r = Math.sin(3.14)? Come si collega a questa domanda? Grazie.
flow2k

1
@ flow2k Oh mio Dio, vecchio commento quindi non posso modificarlo ma è un errore di battitura, dovrebbe dire che "non è mai consentito assegnare al risultato di una chiamata di funzione in Java". Cioè puoi scrivere "foo = bar ();" ma mai "bar () = foo;".
ApproachingDarknessFish

Grazie per il chiarimento @ApproachingDarknessFish. Penso che sarebbe strano assegnare qualcosa al risultato di una funzione - ci sono lingue che lo consentono? Mi chiedo quale sarebbe il caso d'uso.
flow2k,

Risposte:


566

Le stringhe sono immutabili in Java. Non puoi cambiarli.

Devi creare una nuova stringa con il carattere sostituito.

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

Oppure puoi usare StringBuilder:

StringBuilder myName = new StringBuilder("domanokz");
myName.setCharAt(4, 'x');

System.out.println(myName);

3
Ah, vuoi dire come il replacemetodo che non modificherà la stringa ma restituirà solo una nuova stringa?
DP

1
È un po 'complicato Mr.Petar. È questo il modo migliore per farlo? Ah, ho sentito parlare di StringBuilder prima, fa qualche differenza? Mi darà un metodo più semplice?
dpp,

158

Trasforma la stringa in un carattere [], sostituisci la lettera per indice, quindi converti l'array in una stringa.

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

1
Adoro questa soluzione. Ho finito per cambiare la terza riga in myNameChars [index] = character.toCharArray () [0]; per semplificazione. Bella soluzione.
Dale

2
sembra molto meglio dell'altro più bruttomyName.substring(0,4)+'x'+myName.substring(5);
user924

È molto più semplice
Shiva Acharjee il

19

Stringè una classe immutabile in java. Qualsiasi metodo che sembra modificarlo restituisce sempre un nuovo oggetto stringa con modifica.

Se vuoi manipolare una stringa, considera StringBuildero StringBuffernel caso tu abbia bisogno della sicurezza del thread.


12

Sono d'accordo con Petar Ivanov ma è meglio se implementiamo nel modo seguente:

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);       
}

21
e cosa rende migliore la tua soluzione?
DP

6

Come precedentemente risposto qui, le Stringistanze sono immutabili . StringBuffere StringBuildersono mutabili e adatti a tale scopo, sia che tu debba essere sicuro del thread o meno.

Esiste tuttavia un modo per modificare una stringa, ma non lo consiglierei mai perché non è sicuro, non è affidabile e può essere considerato come un imbroglio: puoi usare la riflessione per modificare l' chararray interno contenuto dall'oggetto String. Reflection consente di accedere a campi e metodi che sono normalmente nascosti nell'ambito corrente (metodi privati ​​o campi di un'altra classe ...).

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();
    }
}

4

È possibile sovrascrivere una stringa, come segue:

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

Si noti che la stringa si myNameverifica su entrambe le righe e su entrambi i lati della seconda riga.

Pertanto, anche se le stringhe possono essere tecnicamente immutabili, in pratica, puoi trattarle come modificabili sovrascrivendole.


Non ho sottovalutato la tua risposta, ma devo ammettere che ho un problema con il termine "sovrascrivi" (anche se penso che siamo d'accordo sul concetto alla base). L'oggetto stesso rimane invariato. Devi solo fare in modo che la tua variabile faccia riferimento a un altro oggetto. A proposito, sarà interessante ricordare che nel tuo esempio crei almeno quattro istanze String.
C.Champagne,

0

La prima cosa che avrei dovuto notare è che charAtè un metodo e assegnare valore ad esso usando il segno di uguale non farà nulla. Se una stringa è immutabile, charAtmetodo, per apportare modifiche all'oggetto stringa deve ricevere un argomento contenente il nuovo carattere. Sfortunatamente, la stringa è immutabile. Per modificare la stringa, avevo bisogno di usare StringBuilder come suggerito dal Sig. Petar Ivanov.


-7

questo funzionerà

   String myName="domanokz";
   String p=myName.replace(myName.charAt(4),'x');
   System.out.println(p);

Uscita: domaxokz


1
anche se detesto fortemente questo metodo per consentire la "modificabilità" del lavoro di altri su questo sito StackOverFlow. completamente ingiusto: /
Diabolus Infernalis

2
Errore di sintassi. E anche se corretto, supponiamo che io voglia sostituire la prima 'o' con 'x', anche la seconda 'o' verrà sostituita.
DP

2
Questo sostituirà tutti i personaggi che sono uguali al carattere 4.
Shripad Bhat

1
Problema: myName.replace(myName.charAt(5),'x')ti darà dxmanxkz, che probabilmente non è ciò che è richiesto.
Dawood ibn Kareem,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.