86

I have a sentence that is passed in as a string and I am doing a replace on the word "and" and I want to replace it with " ". And it's not replacing the word "and" with white space. Below is an example of my logic. And when I debug this the logic does fall into the sentence.replace.

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

Is there something I am missing here.

Pshemo
  • 122,468
  • 25
  • 185
  • 269
yams
  • 942
  • 6
  • 27
  • 60

5 Answers5

179

And when I debug this the logic does fall into the sentence.replace.

Yes, and then you discard the return value.

Strings in Java are immutable - when you call replace, it doesn't change the contents of the existing string - it returns a new string with the modifications. So you want:

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

This applies to all the methods in String (substring, toLowerCase etc). None of them change the contents of the string.

Note that you don't really need to do this in a condition - after all, if the sentence doesn't contain "and", it does no harm to perform the replacement:

String sentence = "Define, Measure, Analyze, Design and Verify";
sentence = sentence.replace("and", " ");
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 2
    I've got to call you out on answering a dup instead of voting to close. This problem has been asked & answered so many times before - what's the deal, Jon? – Matt Ball Oct 04 '12 at 19:49
  • 2
    @MattBall While agree the question has being asked repeatedly, I think this is a better answer, IHMO – MadProgrammer Oct 04 '12 at 19:58
  • 20
    @MattBall: As so often happens, I find it quicker to give a good, complete answer than to find a duplicate which *also* has a good answer. I believe (somewhat egotistically, admittedly) that my answer here is better than the accepted one in the duplicate you found, which doesn't even really make technical sense. ("You need to make your string actually equal the changes you make to the string" - what?) Additionally, I wanted to point out the aspect about not needing to check for containment first. – Jon Skeet Oct 04 '12 at 20:02
  • Having had time to think over this I feel this was a better answer. – yams Feb 09 '15 at 18:23
69

Strings are immutable, meaning their contents cannot change. When you call replace(this,that) you end up with a totally new String. If you want to keep this new copy, you need to assign it to a variable. You can overwrite the old reference (a la sentence = sentence.replace(this,that) or a new reference as seen below:

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

    }
}

As an aside, note that I've removed the contains() check, as it is an unnecessary call here. If it didn't contain it, the replace will just fail to make any replacements. You'd only want that contains method if what you're replacing was different than the actual condition you're checking.

corsiKa
  • 81,495
  • 25
  • 153
  • 204
Kumar Vivek Mitra
  • 33,294
  • 6
  • 48
  • 75
  • 41
    The text of this answer implies that it's the `contains()` call which was causing a problem - it wasn't. It was an unnecessary call, but it didn't actually cause any issues. The problem was due to ignoring the return value of `replace`, which isn't explained at all in the answer. – Jon Skeet Oct 04 '12 at 22:50
  • @Mr.Jon Skeet i am really sorry, if the text in the answer implied the other way around...but when i said its not required, i meant it was unnecessary.... fine i will include that in the answer making it more obvious..... – Kumar Vivek Mitra Oct 05 '12 at 06:08
  • wouldn't it be better if you do `sentence.replace(" and", ",");` – Khaled.K Feb 25 '14 at 07:03
  • @JonSkeet and others - I added a paragraph that actually explains what's going on, and moved the misleading text to the end, since it's rather superfluous to the real problem at hand. – corsiKa Oct 17 '14 at 19:58
  • 3
    @corsiKa: I wouldn't have done that as an edit to an existing answer by someone else, to be honest. It's changing the meaning of the answer quite significantly. – Jon Skeet Oct 18 '14 at 07:10
9

You aren't doing anything with the return value of replace. You'll need to assign the result of the method, which is the new String:

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

A String is immutable in java. Methods like replace return a new String.

Your contains test is unnecessary: replace will just no-op if there aren't instances of the text to replace.

pb2q
  • 58,613
  • 19
  • 146
  • 147
  • My contain logic is needed because there are cases where I will not want to replace this. The logic isn't exactly like this, I was just using this as a example. – yams Oct 04 '12 at 19:58
  • @MarkBasler: Your contain logic isn't needed for the sample you gave, so you shouldn't have included it. Good questions should contain only what they need to show the problem - by including code which was pointless in the situation you provided, you've added a distraction to the question. – Jon Skeet Oct 04 '12 at 20:04
  • I was concerned with the contain I was concerned with the replace. – yams Oct 04 '12 at 22:19
  • By the way you mark it as a duplicate and answer it. Stay Classy. – yams Jul 28 '14 at 20:41
  • Hi @MarkBasler: I was trying to help. I don't see a conflict with the two actions: your problem was an extremely common one that comes up asked all the time: java strings are immutable. When I mark a question as duplicate I'm trying to improve the quality of questions and answers here, but at the same time, in leaving an answer specific to your question my hope was to provide you with more immediate help, specific to your example. You might find [this question on meta](http://meta.stackexchange.com/questions/10841/how-should-duplicate-questions-be-handled) useful. – pb2q Jul 29 '14 at 20:21
8

You should re-assign the result of the replacement, like this:

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

Be aware that the String class is immutable, meaning that all of its methods return a new string and never modify the original string in-place, so the result of invoking a method in an instance of String must be assigned to a variable or used immediately for the change to take effect.

Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • Strings should be immutable, but there are bugs with the String lib, that allow you to modify the original string. – yams Oct 04 '12 at 20:04
  • 4
    @MarkBasler: Um, what bugs are you talking about, exactly? And if you're aware that strings are immutable, it's unclear why you expected your code to work at all... – Jon Skeet Oct 04 '12 at 22:49
-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;
    }   
}
Tulu
  • 11
  • 3
    Please don't write code-only answers, instead, explain how your code solves the OP's problem. [From Review](https://stackoverflow.com/review/first-posts/19639043) – Taku May 05 '18 at 02:34