El método de reemplazo de cadena no reemplaza caracteres

79

Tengo una oración que se pasa como una cadena y estoy reemplazando la palabra "y" y quiero reemplazarla con "". Y no reemplaza la palabra "y" con espacios en blanco. A continuación se muestra un ejemplo de mi lógica. Y cuando depuro esto, la lógica cae en la oración.

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

¿Hay algo que me falta aquí?

batatas
fuente
33
Las cuerdas son inmutables.
Matt Ball

Respuestas:

171

Y cuando depuro esto, la lógica cae en la oración.

Sí, y luego descarta el valor devuelto.

Las cadenas en Java son inmutables; cuando llama replace, no cambia el contenido de la cadena existente ; devuelve una nueva cadena con las modificaciones. Entonces quieres:

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

Esto se aplica a todos los métodos en String ( substring, toLowerCaseetc.). Ninguna de ellos cambia el contenido de la cadena.

Tenga en cuenta que realmente no necesita hacer esto en una condición; después de todo, si la oración no contiene "and", no hace ningún daño realizar el reemplazo:

String sentence = "Define, Measure, Analyze, Design and Verify";
sentence = sentence.replace("and", " ");
Jon Skeet
fuente
2
Debo llamarlo por responder un dup en lugar de votar para cerrar. Este problema se ha preguntado y respondido tantas veces antes. ¿Cuál es el problema, Jon?
Matt Ball
2
@MattBall Aunque estoy de acuerdo en que la pregunta se ha hecho repetidamente, creo que esta es una mejor respuesta, IHMO
MadProgrammer
20
@MattBall: Como suele suceder, me resulta más rápido dar una respuesta buena y completa que encontrar un duplicado que también tenga una buena respuesta. Creo (algo egoístamente, es cierto) que mi respuesta aquí es mejor que la aceptada en el duplicado que encontró, lo que ni siquiera tiene sentido técnico. ("Necesitas hacer que tu cadena sea realmente igual a los cambios que realizas en la cadena" - ¿qué?) Además, quería señalar el aspecto de no necesitar verificar primero la contención.
Jon Skeet
Habiendo tenido tiempo para pensar en esto, creo que esta fue una mejor respuesta.
ñame
68

Las cadenas son inmutables , lo que significa que su contenido no puede cambiar. Cuando llamas replace(this,that), terminas con un String totalmente nuevo. Si desea conservar esta nueva copia, debe asignarla a una variable. Puede sobrescribir la referencia anterior (a la sentence = sentence.replace(this,that)o una nueva referencia como se ve a continuación:

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

    }
}

Como acotación al margen, tenga en cuenta que he eliminado el contains()cheque, ya que es una llamada innecesaria aquí. Si no lo contenía, el reemplazo simplemente no hará ningún reemplazo. Solo querrá ese método contiene si lo que está reemplazando fuera diferente de la condición real que está verificando.

Kumar Vivek Mitra
fuente
41
El texto de esta respuesta implica que es la contains()llamada la que estaba causando un problema, no lo estaba. Fue una llamada innecesaria, pero en realidad no causó ningún problema. El problema se debió a ignorar el valor de retorno de replace, que no se explica en absoluto en la respuesta.
Jon Skeet
@ Sr.Jon Skeet, lo siento mucho, si el texto en la respuesta implicaba lo contrario ... pero cuando dije que no era necesario, quise decir que era innecesario ... bien, lo incluiré en la respuesta. es más obvio .....
Kumar Vivek Mitra
¿No sería mejor si lo hicieras?sentence.replace(" and", ",");
Khaled.K
@JonSkeet y otros: agregué un párrafo que realmente explica lo que está sucediendo y moví el texto engañoso al final, ya que es bastante superfluo para el problema real en cuestión.
corsiKa
3
@corsiKa: Para ser honesto, no lo habría hecho como una edición de una respuesta existente de otra persona. Está cambiando el significado de la respuesta de manera bastante significativa.
Jon Skeet
9

No está haciendo nada con el valor de retorno de replace. Deberá asignar el resultado del método, que es el nuevo String:

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

A Stringes inmutable en java. Métodos como replacedevolver un nuevoString .

Su containsprueba es innecesaria: replacesimplemente no funcionará si no hay instancias del texto para reemplazar.

pb2q
fuente
Mi lógica de contenido es necesaria porque hay casos en los que no quiero reemplazar esto. La lógica no es exactamente así, solo estaba usando esto como ejemplo.
ñame
@MarkBasler: su lógica de contenido no es necesaria para la muestra que dio, por lo que no debería haberla incluido. Las buenas preguntas deben contener solo lo que necesitan para mostrar el problema; al incluir un código que no tenía sentido en la situación que proporcionó, ha agregado una distracción a la pregunta.
Jon Skeet
Estaba preocupado por el contenido, estaba preocupado por el reemplazo.
ñame
Por cierto lo marca como duplicado y lo contesta. Mantente elegante.
ñame
Hola @MarkBasler: estaba tratando de ayudar. No veo un conflicto con las dos acciones: su problema era extremadamente común y se le pregunta todo el tiempo: las cadenas de Java son inmutables. Cuando marco una pregunta como duplicada, trato de mejorar la calidad de las preguntas y respuestas aquí, pero al mismo tiempo, al dejar una respuesta específica a su pregunta, mi esperanza era brindarle una ayuda más inmediata, específica para su ejemplo. . Puede encontrar útil esta pregunta en meta .
pb2q
8

Debería reasignar el resultado del reemplazo, así:

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

Tenga en cuenta que la Stringclase es inmutable , lo que significa que todos sus métodos devuelven una nueva cadena y nunca modifican la cadena original en el lugar, por lo que el resultado de invocar un método en una instancia de Stringdebe asignarse a una variable o usarse inmediatamente para la cambiar para que surta efecto.

Óscar López
fuente
Las cadenas deben ser inmutables, pero hay errores con String lib, que le permiten modificar la cadena original.
ñame
4
@MarkBasler: Um, ¿de qué errores estás hablando exactamente? Y si sabe que las cadenas son inmutables, no está claro por qué esperaba que su código funcionara ...
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
fuente
3
No escriba respuestas de solo código, en su lugar, explique cómo su código resuelve el problema del OP. De la opinión
abccd