8

Is there a way to use str.charAt(index) to replace a specific char by index? Something like this:

str.setCharAt(1,'X'); // replace 2nd char with 'X'

Is there any easy way to do that?

moinudin
  • 134,091
  • 45
  • 190
  • 216
evilReiko
  • 19,501
  • 24
  • 86
  • 102

5 Answers5

11

Depending on the source of str you may be able to do something like this:

StringBuilder str = new StringBuilder("Test string");
str.setCharAt(1, 'X');
str.toString();

If you have a string that you are piecing together and modifying a lot, it makes more sense to use a StringBuilder instead of a string. However, if you are modifying a String from another method call, the other answers may be more appropriate.

  • wait!! I'm new to this, but java has StringBuffer and StringBuilder? why don't they just merge all these functions in the basic String class? – evilReiko Jan 02 '11 at 00:57
  • 3
    @evilReiko A String is immutable. I.e. once created it can't change. Its very efficient to use when its not intended to change, but if you need to change its contents you need to use StringBuilder or its Threadsafe cousin StringBuffer. If you are not working in a multithreaded environment (or your StringBuilder instance is only accessible from one thread) a StringBuilder is normally enough. – jbx Jan 02 '11 at 01:48
  • If you have a StringBuffer which is being updated by multi-threads I suggest you change your program so it doesn't ;) – Peter Lawrey Jan 02 '11 at 10:30
  • 1
    Each of the three classes fulfills a specific role, as others have pointed out. One nifty caveat is that the compiler will replace calls to string concatenation to the creation of a StringBuilder, adding elements, and calling toString() at the end. This is the case when you "add" strings, objects, and primitives together. If you concatenate static strings, e.g. "string1" + "string2", the compiler will perform the concatenation in place, rather that delegating to the JVM at runtime. This is all tangential to this discussion but nice to know regardless. –  Jan 03 '11 at 03:03
4

StringBuilder has a setCharAt() method (thanks @John for identifying that you should use it over StringBuffer):

StringBuilder sb = new StringBuilder(str);
sb.setCharAt(1, 'X');
str = sb.toString();

Or you can use substring(), which is a little messy and less efficient:

str = str.substring(0, 1) + 'X' + str.substring(2);

Strings are immutable (well, sort of), so you have to create a new string and assign it to str.

moinudin
  • 134,091
  • 45
  • 190
  • 216
  • Why use `StringBuffer` and the overhead of synchronization for a temporary variable not accessed by multiple threads? `StringBuilder` is more appropriate here (see my answer). –  Jan 02 '11 at 00:45
  • @John Because I was unaware of the distinction. Thanks for pointing that out. – moinudin Jan 02 '11 at 00:46
3

Not sure if this is more or less efficient than the other proposed solutions (though it seems simpler):

char[] chars = str.toCharArray();
chars[1] = 'X';
str = new String(chars);

This is the same approach suggested in a related question.

Community
  • 1
  • 1
dkarp
  • 14,483
  • 6
  • 58
  • 65
1

You can split the string at the index, insert the character and then concatenate the remaining part of the string:

public static String replaceCharAt(String s, int pos, char c)
{
    return s.substring(0, pos) + c + s.substring(pos + 1);
}

Where s is the input string.

Evan Mulawski
  • 54,662
  • 15
  • 117
  • 144
  • That is really inefficient with all the generating of new strings and doesn't look very pretty either. Why not use one of the many methods already supplied in StringBuilder? – Sebastiaan van den Broek Jan 02 '11 at 00:47
  • 1
    The OP asked for an easy way and did not provide any prerequisites, like efficiency. Also, it is always valuable to learn different ways to perform tasks. – Evan Mulawski Jan 02 '11 at 00:53
1

Use the StringBuilder class (not StringBuffer), it has a replace method looking like sb.replace(0, 1, "X"); or if it's always just a char use sb.setCharAt(0, 'X'); and is very useful anyway when you want to mutate strings.

Sebastiaan van den Broek
  • 5,818
  • 7
  • 40
  • 73