String vs StringBuilder in Java

String vs StringBuilder in Java comes down to one idea: a String never changes once it exists, while a StringBuilder is a notepad you can keep editing. Below you'll see why that matters, where StringBuffer fits in, and which one to reach for.

What is a String in Java, and why is it immutable?

A String is a piece of text such as "hello". It is immutable, which means "cannot be changed after it is created". The official Java documentation says strings are constant, so methods that look like they edit a string actually hand back a brand-new one.

public class ImmutableDemo {
    public static void main(String[] args) {
        String name = "java";
        name.toUpperCase();              // result is thrown away
        System.out.println(name);        // still "java"

        String loud = name.toUpperCase(); // keep the new String
        System.out.println(loud);
    }
}
java
JAVA

Line 4 made a new String "JAVA" but we didn't save it, so name stayed the same. That's immutability in action.

Why would Java want strings that can't change?

Because they become safe to share. If many parts of your program (or many threads) hold the same String, nobody can secretly change it under their feet. That's why Strings are used for things like names and map keys.

What is StringBuilder in Java?

StringBuilder is a class that holds a changeable sequence of characters. Its append, insert, delete and reverse methods edit the same object in place. It starts with room for 16 characters and grows automatically when it needs more.

public class BuilderDemo {
    public static void main(String[] args) {
        StringBuilder sb = new StringBuilder("start");
        sb.append("le");        // startle
        sb.insert(4, "le");     // starlet
        sb.reverse();           // telrats
        sb.delete(0, 3);        // rats

        String result = sb.toString();
        System.out.println(result);
    }
}
rats

Line by line:

  • new StringBuilder("start") creates a builder holding "start".
  • append("le") adds text to the end.
  • insert(4, "le") puts text at position 4.
  • reverse() flips the characters around.
  • delete(0, 3) removes characters from position 0 up to (not including) 3.
  • toString() gives you a normal String when you're finished.

Notice that we never wrote sb = sb.append(...). The same object changed each time. You may have seen the same trick with the this keyword, since these methods return this so calls can be chained.

What is the difference between String and StringBuilder?

The big difference is mutability. A String is fixed and every "change" creates a new object. A StringBuilder changes its own contents. That makes StringBuilder the better tool when you add to text many times, and String the better tool for text that stays the same.

Does using + on Strings hurt performance?

For a few joins, no. The + operator is fine and easy to read. The trouble starts inside loops, where each pass can create another temporary String. There, a StringBuilder does the same job with far fewer throwaway objects.

public class LoopDemo {
    public static void main(String[] args) {
        // Fine: a handful of joins
        String greeting = "Hello, " + "Asha" + "!";

        // Better: building text in a loop
        StringBuilder numbers = new StringBuilder();
        for (int i = 1; i <= 5; i++) {
            numbers.append(i).append(' ');
        }
        System.out.println(greeting);
        System.out.println(numbers.toString().trim());
    }
}
Hello, Asha!
1 2 3 4 5

Good to know: the Java documentation says the compiler may implement + using StringBuffer, StringBuilder or StringConcatFactory, depending on the JDK version. So simple one-line joins are already handled for you. A loop that keeps adding to one String is where you should switch to a StringBuilder yourself.

Where does StringBuffer fit in?

StringBuffer is the older, thread-safe sibling of StringBuilder. Its methods are synchronized, so several threads can use one instance safely. StringBuilder has the same methods without that locking, so the documentation recommends it unless threads share the object.

Which one should a beginner use?

StringBuilder. Most of the time a builder lives inside one method and only one thread touches it, so you don't need the extra locking. Moving from one to the other is usually just a change of the class name, since the methods match. If you're curious about sharing data across threads, see thread-safe lists in Java.

How do I compare Strings and StringBuilders?

Use equals to compare String contents. The == operator checks whether two variables point at the same object, which is rarely what you want. StringBuilder does not override equals, so convert to a String first.

public class CompareDemo {
    public static void main(String[] args) {
        String a = new String("hi");
        String b = new String("hi");
        System.out.println(a == b);        // different objects
        System.out.println(a.equals(b));   // same characters

        StringBuilder x = new StringBuilder("hi");
        StringBuilder y = new StringBuilder("hi");
        System.out.println(x.equals(y));                       // object identity only
        System.out.println(x.toString().equals(y.toString())); // compare the text
    }
}
false
true
false
true

When should I use String, StringBuilder or StringBuffer?

Use String for text that stays put. Use StringBuilder when you build or edit text repeatedly, especially in a loop. Use StringBuffer only when one buffer is shared by several threads. Not sure what a class or object is? Start with Java classes and objects.

Quick recap

  • String is immutable: methods return a new String and leave the old one alone.
  • StringBuilder is mutable: append, insert, delete and reverse edit it in place.
  • StringBuffer is the synchronized (thread-safe) version, and slower for it.
  • Use a StringBuilder for loops that build text, then call toString().
  • Compare Strings with equals, not ==.

Where can I read more?

The official reference pages are the best next stop: String, StringBuilder and StringBuffer in the Java SE 21 API documentation.

What's next?

Strings often live inside lists, so try the Java ArrayList tutorial next, or browse the Java keywords list.

Frequently Asked Questions

What is the main difference between String and StringBuilder in Java?

A String can never change after it is created (it is immutable). A StringBuilder holds text you can change in place, using methods like append, insert, delete and reverse. Use String for fixed text and StringBuilder when you build text step by step.

Why is String immutable in Java?

Because the value never changes, a String can be safely shared between parts of a program, and between threads, without anyone worrying that it will be altered. The Java documentation says strings are constant and their values cannot be changed after they are created.

Is StringBuilder faster than String?

When you add to text many times, usually yes. Each change to a String creates a new object, while a StringBuilder edits one buffer. For one or two joins, the difference does not matter, so pick the clearer code.

What is the difference between StringBuilder and StringBuffer?

They offer the same methods. StringBuffer is thread-safe, because its methods are synchronized. StringBuilder is not, which makes it faster. The Java documentation recommends StringBuilder in most cases and StringBuffer only when several threads share one instance.

How do I turn a StringBuilder back into a String?

Call toString() on it. This returns a new String with the current contents. Changing the StringBuilder afterwards does not affect that String.

Can I compare two StringBuilder objects with equals?

Not in a useful way. StringBuilder does not override equals, so it only checks whether both variables point to the same object. Call toString() on both and compare the resulting Strings, or use compareTo.