Java OCAJP7: difference between replace, replaceAll and replaceFirst methods of String class

One thing that might mislead during OCAJP exam, in case you do not have absolute confidence with the signature of the methods of String class, is the difference between replace and replaceAll methods.
The names are a little bit misleading and you may be confusing, even just for haste or carelessness, and think that replaceAll method replaces all the occurrences of a string within another while replace method just replaces one occurrence. This is not true because both methods replace all occurrences that are found.
In the following example we define a test string and then we invoke on it the replaceAll method and then also the replace method.

public class StringReplacingTest {

    public static void main(String[] args) {
        String s = "ABC AA D F AA BA AB CC FA AA A D C BA AA";
        System.out.println(s);

        s = s.replaceAll("AA", "ZZ");
        System.out.println(s);

        s = s.replace("ZZ", "XX");
        System.out.println(s);
    }
}

The result we get is the following, where we see that the replaceAll method replaces all occurrences of “AA” with “ZZ” and then the replace method replaces all occurrences of “ZZ” with “XX”.

ABC AA D F AA BA AB CC FA AA A D C BA AA
ABC ZZ D F ZZ BA AB CC FA ZZ A D C BA ZZ
ABC XX D F XX BA AB CC FA XX A D C BA XX

So, if both methods replace all occurrences of a pattern in a string, what are the differences between the two methods?
To find them we can start from the two methods signature:

  • String replace(CharSequence target, CharSequence replacement)
  • String replaceAll(String regex, String replacement)

The first difference we can notice is that replaceAll takes as parameters two String objects, while replace accepts two implementations of the CharSequence interface (so, as well as String, also StringBuilder, StringBuffer, etc ..)
So we can invoke replace passing as sequence to looking for a StringBuilder object:

public class StringReplacingTest {

    public static void main(String[] args) {
        String s = "ABC AA D F AA BA AB CC FA AA A D C BA AA";
        System.out.println(s);

        StringBuilder sb = new StringBuilder("AA");
        s = s.replace(sb, "XX");
        System.out.println(s);
    }
}

and we get the following result:

ABC AA D F AA BA AB CC FA AA A D C BA AA
ABC XX D F XX BA AB CC FA XX A D C BA XX

But if we try to do the same by calling replaceAll method, we get a compilation error:

public class StringReplacingTest {

    public static void main(String[] args) {
        String s = "ABC AA D F AA BA AB CC FA AA A D C BA AA";
        System.out.println(s);

        StringBuilder sb = new StringBuilder("AA");
        s = s.replaceAll(sb, "ZZ");
        System.out.println(s);
    }
}
The method replaceAll(String, String) in the type String is not applicable for the arguments (StringBuilder, String)

Furthermore, replaceAll takes as its first parameter a string representing a regular expression, while replace just accepts plain old strings and does not interpret regex.
So, if we execute the following code in which we indicate a regex as a sequence to be replaced…

public class StringReplacingTest {

    public static void main(String[] args) {
        String s = "ABC AA D F AA BA AB CC FA AA A D C BA AA";
        System.out.println(s);

        s = s.replaceAll("\\WAA\\W", "ZZ");
        System.out.println(s);
    }
}

we get the following result:

ABC AA D F AA BA AB CC FA AA A D C BA AA
ABCZZD FZZBA AB CC FAZZA D C BA AA

If we execute the same operation with the same sequences, but using the replace method instead

public class StringReplacingTest {

    public static void main(String[] args) {
        String s = "ABC AA D F AA BA AB CC FA AA A D C BA AA";
        System.out.println(s);

        s = s.replace("\\WAA\\W", "XX");
        System.out.println(s);
    }
}

we get the following result, where we can see that no sequence has been replaced, since the regular expression is not evaluated and the method searches for the string “\WAA\W” which of course is not present.

ABC AA D F AA BA AB CC FA AA A D C BA AA
ABC AA D F AA BA AB CC FA AA A D C BA AA

Finally, since both replace and replaceAll methods replace all occurrences of a string within another one, we look now how to replace only the first occurrence . For this purpose we use the replaceFirst method which behaves like the replaceAll method, accepting two String as input and handling even regular expression, but replaces only the first occurrence of the sequence within the string.
The example below shows a summary of the use of all the methods discussed in the article.

public class StringReplacingTest {

    public static void main(String[] args) {
        String s = "ABC AA D F AA BA AB CC FA AA A D C BA AA";
        System.out.println(s);

        s = s.replaceAll("\\WAA\\W", "-ZZ-");
        System.out.println(s);

        StringBuilder sb = new StringBuilder("-ZZ-");

        s = s.replace(sb, "_XX_");
        System.out.println(s);

        s = s.replaceFirst("_XX_", "YY");
        System.out.println(s);
    }
}
ABC AA D F AA BA AB CC FA AA A D C BA AA
ABC-ZZ-D F-ZZ-BA AB CC FA-ZZ-A D C BA AA
ABC_XX_D F_XX_BA AB CC FA_XX_A D C BA AA
ABCYYD F_XX_BA AB CC FA_XX_A D C BA AA

As we can see, the replacement of “_XX_” with “YY” is performed only on the first occurrence and not every time it appears.

This entry was posted in $1$s. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *