Метод замены строки не заменяет символы


79

У меня есть предложение, которое передается в виде строки, и я заменяю слово «и», и я хочу заменить его на «». И это не замена слова «и» на пробел. Ниже приведен пример моей логики. И когда я отлаживаю это, логика попадает в предложение .replace.

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

Что-то мне здесь не хватает.


33
Строки неизменны.
Мэтт Болл,

Ответы:


171

И когда я отлаживаю это, логика попадает в предложение .replace.

Да, а потом отбрасываете возвращаемое значение.

Строки в Java неизменяемы - когда вы вызываете replace, он не меняет содержимое существующей строки - он возвращает новую строку с изменениями. Итак, вы хотите:

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

Это относится ко всем методам в String ( substringи toLowerCaseт. Д.). Ни один из них не меняет содержимое строки.

Обратите внимание, что вам не обязательно делать это в условии - в конце концов, если предложение не содержит "and", выполнение замены не повредит:

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

2
Я должен призвать вас ответить на обман вместо того, чтобы голосовать за закрытие. Эту проблему уже много раз задавали и отвечали - в чем дело, Джон?
Мэтт Болл,

2
@MattBall Хотя согласен, что вопрос задавали неоднократно, я думаю, что это лучший ответ, IHMO
MadProgrammer

20
@MattBall: Как это часто бывает, я считаю, что быстрее дать хороший полный ответ, чем найти дубликат, который также имеет хороший ответ. Я считаю (правда, несколько эгоистично), что мой ответ здесь лучше, чем принятый в найденном вами дубликате, который даже не имеет технического смысла. («Вам нужно, чтобы ваша строка фактически соответствовала изменениям, которые вы вносите в строку» - что?) Кроме того, я хотел указать на аспект о том, что не нужно сначала проверять на предмет содержания.
Джон Скит,

Имея время подумать над этим, я считаю, что это был лучший ответ.
yams

68

Строки неизменяемы , то есть их содержимое не может измениться. Когда вы звоните, replace(this,that)вы получаете совершенно новую строку. Если вы хотите сохранить эту новую копию, вам нужно присвоить ее переменной. Вы можете перезаписать старую ссылку (а-ля sentence = sentence.replace(this,that)или новую ссылку, как показано ниже:

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

    }
}

Кстати, обратите внимание, что я удалил contains()чек, так как здесь нет необходимости. Если он не содержал его, при замене не будет никаких замен. Вам нужно, чтобы он содержал метод, только если то, что вы заменяете, отличалось от фактического состояния, которое вы проверяете.


41
Текст этого ответа подразумевает, что contains()проблема возникла из-за звонка, но это не так. Это был ненужный звонок, но на самом деле он не вызвал никаких проблем. Проблема заключалась в игнорировании возвращаемого значения replace, которое вообще не объясняется в ответе.
Джон Скит,

@ Мистер Джон Скит, мне очень жаль, если текст в ответе подразумевает обратное ... но когда я сказал, что это не требуется, я имел в виду, что это не нужно ... хорошо, я включу это в ответ это более очевидно .....
Кумар Вивек Митра

не будет ли лучше, если вы это сделаетеsentence.replace(" and", ",");
Khaled.K

@JonSkeet и другие - я добавил абзац, который фактически объясняет, что происходит, и переместил вводящий в заблуждение текст в конец, так как он довольно излишний для реальной проблемы.
corsiKa

3
@corsiKa: Честно говоря, я бы не стал редактировать существующий ответ кем-то другим. Это довольно существенно меняет смысл ответа.
Джон Скит

9

Вы ничего не делаете с возвращаемым значением replace. Вам нужно будет назначить результат метода, который является новым String:

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

A Stringнеизменен в java. Такие методы, как replaceвозврат нового String.

Ваш containsтест не нужен: replaceпросто не будет работать, если нет экземпляров текста для замены.


Моя логика сдерживания необходима, потому что есть случаи, когда я не хочу ее заменять. Логика не совсем такая, я просто использовал это в качестве примера.
yams

@MarkBasler: ваша логика содержания не нужна для предоставленного вами образца, поэтому вам не следовало включать ее. Хорошие вопросы должны содержать только то, что им нужно, чтобы показать проблему - включив код, который был бессмысленным в той ситуации, которую вы указали, вы добавили отвлечение к вопросу.
Джон Скит,

Я беспокоился о содержании, я был озабочен заменой.
yams

Кстати отметьте это как дубликат и ответьте на него. Оставайся классным.
yams

Привет, @MarkBasler: Я пытался помочь. Я не вижу конфликта между этими двумя действиями: ваша проблема была чрезвычайно распространенной, и ее постоянно спрашивали: строки java неизменяемы. Когда я помечаю вопрос как повторяющийся, я пытаюсь улучшить качество вопросов и ответов здесь, но в то же время, оставляя ответ, относящийся к вашему вопросу, я надеялся предоставить вам более немедленную помощь, специфичную для вашего примера . Вы можете найти этот вопрос по мета полезным.
pb2q

8

Вам следует переназначить результат замены, например:

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

Имейте в виду, что Stringкласс является неизменным , что означает, что все его методы возвращают новую строку и никогда не изменяют исходную строку на месте, поэтому результат вызова метода в экземпляре Stringдолжен быть назначен переменной или немедленно использован для изменения вступят в силу.


Строки должны быть неизменяемыми, но в String lib есть ошибки, которые позволяют вам изменять исходную строку.
yams

4
@MarkBasler: Хм, о каких именно ошибках ты говоришь? И если вы знаете, что строки неизменяемы, непонятно, почему вы ожидали, что ваш код вообще будет работать ...
Джон Скит,

-1
package com.tulu.ds;

public class EmailSecurity {
    public static void main(String[] args) {
        System.out.println(returnSecuredEmailID("sample717@gmail.com"));
    }
    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;
    }   
}

3
Пожалуйста, не пишите ответы, состоящие только из кода, вместо этого объясните, как ваш код решает проблему OP. Из
отзыва
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.