Die Methode zum Ersetzen von Zeichenfolgen ersetzt keine Zeichen

79

Ich habe einen Satz, der als Zeichenfolge übergeben wird, und ich ersetze das Wort "und" und möchte ihn durch "" ersetzen. Und es ersetzt nicht das Wort "und" durch Leerzeichen. Unten ist ein Beispiel meiner Logik. Und wenn ich dies debugge, fällt die Logik in den Satz.

String sentence = "Define, Measure, Analyze, Design and Verify"
if (sentence.contains("and")){
    sentence.replace("and", " ");
}

Fehlt mir hier etwas?

Yamswurzeln
quelle
33
Saiten sind unveränderlich.
Matt Ball

Antworten:

171

Und wenn ich dies debugge, fällt die Logik in den Satz.

Ja, und dann verwerfen Sie den Rückgabewert.

Zeichenfolgen in Java sind unveränderlich. Wenn Sie aufrufen replace, wird der Inhalt der vorhandenen Zeichenfolge nicht geändert. Es wird eine neue Zeichenfolge mit den Änderungen zurückgegeben. Also du möchtest:

sentence = sentence.replace("and", " ");

Dies gilt für alle Verfahren , die in String ( substring, toLowerCaseusw.). Keiner von ihnen ändert den Inhalt der Zeichenfolge.

Beachten Sie, dass Sie dies unter bestimmten Bedingungen nicht wirklich tun müssen. Wenn der Satz keinen Satz enthält "and", schadet es schließlich nicht, den Ersatz durchzuführen:

String sentence = "Define, Measure, Analyze, Design and Verify";
sentence = sentence.replace("and", " ");
Jon Skeet
quelle
2
Ich muss Sie anrufen, um einen Dup zu beantworten, anstatt für den Abschluss zu stimmen. Dieses Problem wurde schon so oft gestellt und beantwortet - was ist los, Jon?
Matt Ball
2
@ MattBall Obwohl ich damit einverstanden bin, dass die Frage wiederholt gestellt wurde, denke ich, dass dies eine bessere Antwort ist, IHMO
MadProgrammer
20
@MattBall: Wie so oft finde ich es schneller, eine gute, vollständige Antwort zu geben, als ein Duplikat zu finden, das auch eine gute Antwort hat. Ich glaube (zugegebenermaßen etwas egoistisch), dass meine Antwort hier besser ist als die akzeptierte in dem Duplikat, das Sie gefunden haben, was technisch nicht einmal sinnvoll ist. ("Sie müssen dafür sorgen, dass Ihre Zeichenfolge tatsächlich den Änderungen entspricht, die Sie an der Zeichenfolge vornehmen" - was?) Außerdem wollte ich auf den Aspekt hinweisen, dass Sie nicht zuerst auf Eindämmung prüfen müssen.
Jon Skeet
Nachdem ich Zeit hatte, darüber nachzudenken, halte ich dies für eine bessere Antwort.
Yamswurzeln
68

Zeichenfolgen sind unveränderlich , dh ihr Inhalt kann sich nicht ändern. Wenn Sie anrufen, erhalten replace(this,that)Sie einen völlig neuen String. Wenn Sie diese neue Kopie behalten möchten, müssen Sie sie einer Variablen zuweisen. Sie können die alte Referenz überschreiben (a la sentence = sentence.replace(this,that)oder eine neue Referenz wie unten gezeigt:

public class Test{

    public static void main(String[] args) {

        String sentence = "Define, Measure, Analyze, Design and Verify";

        String replaced = sentence.replace("and", "");
        System.out.println(replaced);

    }
}

Beachten Sie außerdem, dass ich den contains()Scheck entfernt habe , da es sich hier um einen unnötigen Aufruf handelt. Wenn es nicht enthalten ist, kann das Ersetzen einfach keine Ersetzungen vornehmen. Sie möchten nur, dass diese Methode enthält, wenn sich das, was Sie ersetzen, von dem tatsächlichen Zustand unterscheidet, den Sie überprüfen.

Kumar Vivek Mitra
quelle
41
Der Text dieser Antwort impliziert, dass es der contains()Anruf ist, der ein Problem verursacht hat - es war nicht so. Es war ein unnötiger Anruf, der jedoch keine Probleme verursachte. Das Problem war darauf zurückzuführen, dass der Rückgabewert von ignoriert wurde replace, was in der Antwort überhaupt nicht erklärt wird.
Jon Skeet
@ Mr.Jon Skeet Es tut mir wirklich leid, wenn der Text in der Antwort umgekehrt impliziert ... aber als ich sagte, dass es nicht erforderlich ist, meinte ich, dass es unnötig war ... gut, ich werde das in die Antwort einbeziehen es ist offensichtlicher .....
Kumar Vivek Mitra
Wäre es nicht besser, wenn Sie es tunsentence.replace(" and", ",");
Khaled.K
@ JonSkeet und andere - Ich habe einen Absatz hinzugefügt, der tatsächlich erklärt, was los ist, und den irreführenden Text an das Ende verschoben, da er für das eigentliche Problem ziemlich überflüssig ist.
CorsiKa
3
@corsiKa: Um ehrlich zu sein, hätte ich das nicht als Bearbeitung einer vorhandenen Antwort von jemand anderem getan. Es ändert die Bedeutung der Antwort erheblich.
Jon Skeet
9

Sie machen nichts mit dem Rückgabewert von replace. Sie müssen das Ergebnis der neuen Methode zuweisen String:

sentence = sentence.replace("and", " ");

A Stringist in Java unveränderlich. Methoden wie replaceein neues zurückgeben String.

Ihr containsTest ist nicht erforderlich: replaceWird nur dann nicht ausgeführt, wenn keine zu ersetzenden Textinstanzen vorhanden sind.

pb2q
quelle
Meine Enthalten-Logik wird benötigt, da es Fälle gibt, in denen ich diese nicht ersetzen möchte. Die Logik ist nicht genau so, ich habe dies nur als Beispiel verwendet.
Yamswurzeln
@MarkBasler: Ihre Enthalten-Logik wird für das von Ihnen angegebene Beispiel nicht benötigt, daher sollten Sie sie nicht einschließen. Gute Fragen sollten nur das enthalten, was sie benötigen, um das Problem aufzuzeigen. Indem Sie Code einfügen, der in der von Ihnen angegebenen Situation sinnlos war, haben Sie der Frage eine Ablenkung hinzugefügt.
Jon Skeet
Ich befasste mich mit dem Inhalt, den ich mit dem Ersetzen befasste.
Yamswurzeln
Übrigens markieren Sie es als Duplikat und beantworten es. Bleib edel.
Süßkartoffeln
Hi @MarkBasler: Ich habe versucht zu helfen. Ich sehe keinen Konflikt mit den beiden Aktionen: Ihr Problem war ein äußerst häufiges, das ständig gefragt wurde: Java-Strings sind unveränderlich. Wenn ich eine Frage als Duplikat markiere, versuche ich, die Qualität der Fragen und Antworten hier zu verbessern. Gleichzeitig wollte ich Ihnen eine schnellere Hilfe geben, die auf Ihr Beispiel zugeschnitten ist, indem ich eine Antwort für Ihre Frage hinterlasse . Vielleicht finden Sie diese Frage auf Meta nützlich.
pb2q
8

Sie sollten das Ergebnis des Austauschs wie folgt neu zuweisen:

 sentence = sentence.replace("and", " ");

Beachten Sie, dass die StringKlasse unveränderlich ist. Dies bedeutet, dass alle Methoden eine neue Zeichenfolge zurückgeben und die ursprüngliche Zeichenfolge niemals Stringdirekt ändern. Daher muss das Ergebnis des Aufrufs einer Methode in einer Instanz von einer Variablen zugewiesen oder sofort für die verwendet werden ändern, um wirksam zu werden.

Óscar López
quelle
Strings sollten unveränderlich sein, aber es gibt Fehler in der String-Bibliothek, mit denen Sie den ursprünglichen String ändern können.
Yamswurzeln
4
@ MarkBasler: Ähm, über welche Fehler sprichst du genau? Und wenn Sie wissen, dass Zeichenfolgen unveränderlich sind, ist es unklar, warum Sie erwartet haben, dass Ihr Code überhaupt funktioniert ...
Jon Skeet
-1
package com.tulu.ds;

public class EmailSecurity {
    public static void main(String[] args) {
        System.out.println(returnSecuredEmailID("[email protected]"));
    }
    private static String returnSecuredEmailID(String email){
        String str=email.substring(1, email.lastIndexOf("@")-1);
        return email.replaceAll(email.substring(1, email.lastIndexOf("@")-1),replacewith(str.length(),"*"));
    }
    private static String replacewith(int length,String replace) {
        String finalStr="";
        for(int i=0;i<length;i++){
            finalStr+=replace;
        }
        return finalStr;
    }   
}
Tulu
quelle
3
Bitte schreiben Sie keine Nur-Code-Antworten, sondern erklären Sie, wie Ihr Code das Problem des OP löst. Aus dem Rückblick
abccd