Strings in Java — Top 3 Best practices

Arvind Telharkar
Effective Java
Published in
3 min readDec 16, 2021

Strings are extremely common in Java programming. In practice, there are a few things which can improve the way you handle strings in code. Some of these can help you safeguard against poor performance or null pointer exceptions, or help you debug better.

Photo by Temple Cerulean on Unsplash

1. StringBuilder for concatenation

It is tempting to use the “+” operator for concatenating strings. Strings are immutable in Java. Hence, when you try to concatenate 2 strings with “+”, contents of both strings are copied. If you do this and put a loop on with lots of iterations, your string concatenation is going to be extremely slow — O(N^2) time!

Consider this snippet — This is going to be very slow for a large value of N and therefore should be avoided in practice.

// A function which reads a file with N lines
public String readFile() {
String fileContents = '';
for(int i=0;i<N;i++) {

/*
Assume readLine(i) is implemented
returning a string for ith Line
*/
fileContents = fileContents + readLine(i);
}

return fileContents;
}

In such situations, always use StringBuilder class. StringBuilder is essentially a sequence of characters, which is mutable — unlike the immutable “String”.

Just use the append() method for StringBuilder to add more characters or strings. You can always convert a StringBuilder to a “String” by using the toString() method. The Javadoc for StringBuilder can be found here.

The above example would look as follows —

public String readFile() {  StringBuilder sb = new StringBuilder();

for(int i=0;i<N;i++) {
sb.append(readLine(i));
}
// Return back the "String" by calling toString()
return sb.toString();
}

2. CONSTANT.equals(variable) — Not the other way round!

The equals() method is extremely common in practice to compare strings and take some action. There is caveat to remember here. Consider the code snippet below —

public final Class Announcer {// Just a constant used in the below method
private static final String ANNOUNCER_NAME = "Hero";
public void announce(String input) {
if(input.equals(ANNOUNCER_NAME)) {
// Do something for announcing
}
}

If the input name does not match “Hero”, we do don’t want the code to take any action and exit silently. But what happens if input is null ? The Code would throw a NullPointerException since we would be doing null.equals(something) which is not allowed. Some people would argue that we can check if input is null at the beginning — Correct, but that might not happen everywhere where the equals() is being used!

To avoid there pitfalls, always follow the convention of CONSTANT.equals(variable). Hence, the condition above should be refactored as —

public void announce(String input) {
if(ANNOUNCER_NAME.equals(input)) {
// Do something for announcing
}
}

ANNOUNCER_NAME is never going to be null. Hence if input is null, we will just get ANNOUNCER_NAME.equals(null), which is false — the code exits as intended without throwing a NullPointerException.

3. toString() implementation

Anytime you have an object, you should have a user-friendly, human-readable toString() method implementation for it. IDEs like Intellij and Eclipse have the facility to auto-generate and implement those methods for you, using a combination of class member fields. Having a good toString() method implemented, makes life easier during debugging. There is a default toString() method used if you don’t implement a custom one. It would create the string representation of an Employee class as “Employee@345981”(just an example), whereas if you override toString() and use your own format, it can look something like “name=David, age=25”(just an example — You can return whatever representation you like when you override!). While debugging, would you like to see the object of an Employee class stringified as “Employee@345981”, or as “name=David, age=25” ?

If you want to connect with me, feel free to reach out on LinkedIn!

To take your Java development skills to the next level, be sure to checkout and follow Effective Java!

--

--