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


79

У мене є речення, яке передається як рядок, і я замінюю слово "і", і я хочу замінити його на "". І це не заміна слова "і" пробілом. Нижче наведено приклад моєї логіки. І коли я налагоджую це, логіка справді потрапляє у речення.replace.

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

Чи є щось, чого мені тут не вистачає.


33
Струни незмінні.
Matt Ball

Відповіді:


171

І коли я налагоджую це, логіка справді потрапляє у речення.replace.

Так, і тоді ви відкидаєте повернене значення.

Рядки в Java незмінні - коли ви телефонуєте replace, це не змінює вміст існуючого рядка - він повертає новий рядок із змінами. Отже, ви хочете:

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

Це стосується всіх методів у рядку ( substring, toLowerCaseтощо). Жоден з них не змінює вміст рядка.

Зверніть увагу, що вам насправді не потрібно робити це в умовах - зрештою, якщо речення не містить "and", виконувати заміну не шкодить:

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

2
Я повинен зателефонувати вам, відповідаючи на дубль, замість того, щоб голосувати за закриття. Цю проблему вже стільки разів задавали і відповідали - у чому справа, Джон?
Matt Ball

2
@MattBall Хоча погодьтеся, що питання задавали неодноразово, я думаю, що це краща відповідь, IHMO
MadProgrammer

20
@MattBall: Як це часто буває, я вважаю, що швидше дати хорошу, повну відповідь, ніж знайти дублікат, який також має хорошу відповідь. Я вважаю (дещо егоїстично, правда), що моя відповідь тут краща за прийняту у тому дублікаті, який ви знайшли, що навіть насправді не має технічного сенсу. ("Вам потрібно зробити так, щоб ваш рядок насправді відповідав змінам, які ви вносите в рядок" - що?) Крім того, я хотів вказати на аспект непотрібності перевіряти наявність стримування спочатку.
Джон Скіт,

Встигнувши подумати над цим, я вважаю, що це була краща відповідь.
ямс

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, що взагалі не пояснено у відповіді.
Джон Скіт,

@ Mr.Jon Skeet Мені дуже шкода, якщо текст у відповіді мав на увазі навпаки ... але коли я сказав, що це не потрібно, я мав на увазі, що це було непотрібним ... чудово, я включу це у відповідь це очевидніше .....
Кумар Вівек Мітра

чи не буде краще, якщо ви це зробитеsentence.replace(" and", ",");
Халед. К

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

3
@corsiKa: Чесно кажучи, я б не зробив цього як редагування існуючої відповіді. Це досить суттєво змінює значення відповіді.
Джон Скіт,

9

Ви нічого не робите із поверненим значенням replace. Вам потрібно буде призначити результат методу, який є новим String:

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

A Stringнезмінна в Java. Такі методи, як replaceповернення нового String.

Ваш containsтест НЕ є необхідним: replaceне тільки не-оп , якщо НЕ екземпляри тексту замінити.


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

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

Мене турбувало вміст, я турбувався про заміну.
ямс

До речі ви позначаєте це як дублікат і відповідаєте на нього. Залишитися класний.
ямс

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

8

Вам слід повторно призначити результат заміни, наприклад:

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

Майте на увазі, що Stringклас незмінний , тобто всі його методи повертають новий рядок і ніколи не змінюють оригінальний рядок на місці, тому результат виклику методу в екземплярі Stringповинен бути призначений змінній або негайно використаний для зміна набуде чинності.


Рядки повинні бути незмінними, але є помилки з бібліотекою String, які дозволяють вам змінити вихідний рядок.
ямс

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. З огляду
abccd
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.