StringBuilder and StringBuffer in Java: Examples and Interview Exercises

Brandon Wohlwend
7 min readAug 8, 2023

--

Welcome back studying with me Java! In programming, mastering the art of string manipulation is crucial. It is not just about joining words together or searching for patterns, it is about efficiently crafting and transforming strings. This is where very useful tools, provided by Java, comes into play: String, StringBuilder and StringBuffer classes.

Imagine you are constructing a dynamic message that requires constant modifications or concatening large amounts of text efficiently. The basic String class in Java might seem like a handy option, but as your program grows, its immutable nature can lead to performance issues and unnecessary memory consumption.

Enter StringBuilder and StringBuffer. These two classes are like toolkits for building, modifying and transforming strings on the fly. They allow you to create dynamic strings with improved efficiency, making your code faster and more responsive.

Guess what. In this article we will take a look at these classes. We will dive deeo into the differences, exploring their strengths and best use cases. We will also discuss some examples and coding exercises. Without further ado, lets get into it!

Understanding String, StringBuilder and StringBuffer

String

We all know it. The String class in Java is the most basic way to represent and work with text. It is simple to use and provides several methods for string manipulation. However, it comes with a big limitation: Immutability. Once a String object is created, it cannot be modified. Any operation that appears to modidy a string actually creates a new string object.

Each time you perform an operation on a string (eg concatenation or substring extraction), a new string is created in memory. Puh. This can lead to increased memory usage, especially when working with large strings or when you perfrom multiple operations. But of course, there is help:

StringBuilder and StringBuffer

To address the limiations of the immutable String class, Java provides two other classes: StringBuilder and StringBuffer. These classes are designed for efficient string manipulation and dynamic content creation

StringBuilder

This is an unsynchronized, mutable sequence of characters. It is designed for single-threaded scenarios where performance is crucial. With StringBuilder, you can append, insert or delete characters within the same object, avoiding the need to create multiple intermediate string objects. Good for dynamic string construction and concatenation.

StringBuffer

Similar to StringBuilder, StringBuffer also provides mutable sequences of characters. However, unlike StringBuilder, StringBuffer is synchronized, making it thread-safe. This means that multiple threads can manipulate a StringBuffer object concurrently without causing data corruption. However, this thread safety comes at the cost of some performance.

It’s worth noting that both StringBuilder and StringBuffer belong to the java.lang package. This means that you don't need to import any additional packages to use them; they are readily available for use in your Java programs.

Practical Examples

Example 1: Basic String Manipulation with StringBuilder

You want to create a sentence by concatenating several words together. Lets compare two approaches: Using StringBuilder and using simple string concatenation.

a) Using StringBuilder

public class StringBuilderExample {
public static void main(String[] args) {
StringBuilder sentenceBuilder = new StringBuilder();

sentenceBuilder.append("This");
sentenceBuilder.append(" is");
sentenceBuilder.append(" a");
sentenceBuilder.append(" StringBuilder");
sentenceBuilder.append(" example.");

String sentence = sentenceBuilder.toString();
System.out.println(sentence);
}
}

Here, we create a StringBuilder named sentenceBuilder and successively append individual words to it. Finally, we convert the StringBuilder to a String using the toString() method and print the resulting sentence.

b) Using String Concatenation

Now, lets see this approach with string concatenation

public class StringConcatenationExample {
public static void main(String[] args) {
String sentence = "This" + " is" + " a" + " simple" + " concatenation" + " example.";

System.out.println(sentence);
}
}

Here, for each concatenation operation it creates intermediate string objects. This can lead to performance issues, especially when dealing with longer strings.

c) Lets compare the performance

To emphasize the performance gains of using StringBuilder, lets measure the execution times of both approaches using the System.nanoTime() method

public class PerformanceComparison {
public static void main(String[] args) {
long startTimeStringBuilder = System.nanoTime();
StringBuilder sentenceBuilder = new StringBuilder();

for (int i = 0; i < 10000; i++) {
sentenceBuilder.append("word");
}

String sentence = sentenceBuilder.toString();
long endTimeStringBuilder = System.nanoTime();
long elapsedTimeStringBuilder = endTimeStringBuilder - startTimeStringBuilder;
System.out.println("Using StringBuilder: " + elapsedTimeStringBuilder + " nanoseconds");

long startTimeConcatenation = System.nanoTime();
String sentenceConcatenation = "";

for (int i = 0; i < 10000; i++) {
sentenceConcatenation += "word";
}

long endTimeConcatenation = System.nanoTime();
long elapsedTimeConcatenation = endTimeConcatenation - startTimeConcatenation;
System.out.println("Using String Concatenation: " + elapsedTimeConcatenation + " nanoseconds");
}
}

You will see that using StringBuilder results in significantly faster execution times due to reduced overhead from object creation and copying.

Example 2: Reversing a String

We will explore how both StringBuilder and StringBuffer make this task more efficient due to their mutability, and we will compare the two approaches to highlight their benefits.

a) Using StringBuilder

public class ReverseStringBuilderExample {
public static void main(String[] args) {
String originalString = "Hello, world!";
StringBuilder reversedBuilder = new StringBuilder(originalString);

reversedBuilder.reverse();
String reversedString = reversedBuilder.toString();

System.out.println("Original: " + originalString);
System.out.println("Reversed: " + reversedString);
}
}

Here, we create a StringBuilder with the original string, then use the reverse() method to reverse the characters within the StringBuilder. Finally we convert the StringBuilder back to a String and print the original reversed strings.

b) Using StringBuffer

public class ReverseStringBufferExample {
public static void main(String[] args) {
String originalString = "Hello, world!";
StringBuffer reversedBuffer = new StringBuffer(originalString);

reversedBuffer.reverse();
String reversedString = reversedBuffer.toString();

System.out.println("Original: " + originalString);
System.out.println("Reversed: " + reversedString);
}
}

This approach is very similar to the one using StringBuilder. We create a StringBuffer, reverse its content, and convert it back to a String for printing.

c) Comparing approaches

Both StringBuilder and StringBuffer provide efficient solutions for reversing strings. Their mutability allows for in-place modifications, resulting in less memory usage and better performance compared to approaches that create new string objects.

Example 3: Building Comma-Separeted Strings

In this example, we will address a common programming task: constructing comma-separated strings from a list of items. We will utilize the efficiency of StringBuilder to create such strings without generating multiple intermediate string objects

Using StringBuilder

import java.util.ArrayList;
import java.util.List;

public class CommaSeparatedStringBuilderExample {
public static void main(String[] args) {
List<String> items = new ArrayList<>();
items.add("apple");
items.add("banana");
items.add("orange");
items.add("grape");

StringBuilder csvBuilder = new StringBuilder();

for (String item : items) {
if (csvBuilder.length() > 0) {
csvBuilder.append(", ");
}
csvBuilder.append(item);
}

String csvString = csvBuilder.toString();
System.out.println("Comma-separated list: " + csvString);
}
}

Here, we have a list of items and we want to create a comma-separated string from them. Using StringBuilder, we iteratively append each item to the builder. We include a check to insert a comma and space before each item except the first one, ensuring proper formatting.

Now lets see some common coding excersices

Coding Exercises for Job Interviews

Exercise 1: Anagram Check — String

An anagram is a word or phrase formed by rearranging the letters of another word or phrase. The task is to determine if two given strings are anagrams of each other.

So our task is to write a function that takes two strings as input and returns true if the strings are anagrams and false otherwise.

public class AnagramChecker {
public static void main(String[] args) {
String str1 = "listen";
String str2 = "silent";

boolean areAnagrams = areAnagrams(str1, str2);
System.out.println("Are the strings anagrams? " + areAnagrams);
}

public static boolean areAnagrams(String str1, String str2) {
if (str1.length() != str2.length()) {
return false;
}

int[] charCount = new int[256]; // Assuming ASCII characters

for (char c : str1.toCharArray()) {
charCount[c]++;
}

for (char c : str2.toCharArray()) {
charCount[c]--;
}

for (int count : charCount) {
if (count != 0) {
return false;
}
}

return true;
}
}

In this solution we use an array charCount to keep track of the frequency of each character in str1. We then iterate through str2 and decrement the corresponding character count. If both strings are anagrams, all character counts will be zero at the end of the process.

Exercise 2: Palindrome Check

A palindrome is a word, phrase, number or other sequences of characters that reads the same forward and backward.

So our task is to write a function that takes a string as input and returns true if the string is a palindrome, and false otherwise.

public class PalindromeChecker {
public static void main(String[] args) {
String str = "racecar";

boolean isPalindrome = isPalindrome(str);
System.out.println("Is the string a palindrome? " + isPalindrome);
}

public static boolean isPalindrome(String str) {
StringBuilder reversedBuilder = new StringBuilder(str).reverse();
String reversedString = reversedBuilder.toString();

return str.equalsIgnoreCase(reversedString);
}
}

Here, we use StringBuilder to reverse the input string and then we compare the reversed string with the original string, ignoring case. If they are qual, the input is a palindrome.

Exercise 3: Counting Occurrences

The challenge is to count the occurrences of each character in a given string and create a summary report.

So our task is to write a function that takes a string as input and returns a summary report of the character occurrences in the format “Character: Count”. Each character should appear only once in the report and characters should be presented in the order they appear in the input string.

import java.util.HashMap;
import java.util.Map;

public class CharacterCounter {
public static void main(String[] args) {
String input = "programming";

String summaryReport = generateSummaryReport(input);
System.out.println("Character Occurrences:\n" + summaryReport);
}

public static String generateSummaryReport(String input) {
Map<Character, Integer> charCountMap = new HashMap<>();
StringBuilder reportBuilder = new StringBuilder();

for (char c : input.toCharArray()) {
charCountMap.put(c, charCountMap.getOrDefault(c, 0) + 1);
}

for (Map.Entry<Character, Integer> entry : charCountMap.entrySet()) {
reportBuilder.append(entry.getKey())
.append(": ")
.append(entry.getValue())
.append("\n");
}

return reportBuilder.toString();
}
}

Here, we use a Map to keep track of character occurrences. We iterate through the input string, updating the count of each character in the Map. Then we use StringBuilder to efficiently construct the summary report by appending each character and its count.

Conclusion

We are done. It wasnt that complicated, wasnt it? We now know what StringBuilder and StringBuffer is and when to use them. We have seen some examples and even discussed some Job related coding exercises. If you dont want to miss out any new article about Java, Data Science or other tech stuff, feel free to follow me!

--

--

Brandon Wohlwend

Mathematician | Data Science, Machine Learning | Java, Software Engineering