1. Overview
In this guide, I would like to explain the best practices for String Handling. This post belongs to Java Best Practices Series category. Basically, this guide explains how effectively we can use String in the day to day project work.
Check out beginners to expert String Tutorial/Guide at Java String API Guide/Tutorial
Video
This article nicely explained in below YouTube video:
2. String Best Practices in Java
Let's discuss each String best practices with an example.2.1. Use StringBuilder or StringBuffer for string concatenations instead of the + operator
If you have more string concatenation operations, then prefer using StringBuilder object over the + operator.StringBuffer acts like StringBuilder, as it has the same methods except they are synchronized. That means StringBuffer should be used in multi-threading context.
Let's write a simple program to demonstrate the performance of String, StringBuilder, and StringBuffer.
public class PerformanceTest{
public static void main(String []args){
String str = "";
long startTime = System.nanoTime();
for(int i=0 ; i < 10 ; i++) {
str = str + i;
}
long endTime = System.nanoTime();
System.out.println(String.format("String opetation with
+ operator took [%d] nano seconds",(endTime-startTime)));
StringBuilder builder = new StringBuilder();
startTime = System.nanoTime();
for(int i=0;i<10;i++) {
builder.append(i);
}
endTime = System.nanoTime();
System.out.println(String.format("String opetation with
StringBuilder took [%d] nano seconds",(endTime-startTime)));
StringBuffer strBuffer = new StringBuffer();
startTime = System.nanoTime();
for(int i=0;i<10;i++) {
strBuffer.append(i);
}
endTime = System.nanoTime();
System.out.println(String.format("String opetation with
StringBuffer took [%d] nano seconds",(endTime-startTime)));
}
}
Output:
String opetation with + operator took [86037] nano seconds
String opetation with StringBuilder took [7928] nano seconds
String opetation with StringBuffer took [14165] nano seconds
From above result note that StringBuilder and StringBuffer for String concatenation are more faster than String concatenation using + operator.
Eclipse Tip
Did you know, in Eclipse you can automatically convert '+' String concatenations to StringBuilder append()s? It also picks the right append() depending on the type. Ctrl+1 is very handy!2.2. Compare Two String by equals() Method Instead == Operator
Refer below points while comparing string contents and string references.- use == to compare primitive e.g. boolean, int, char etc, while use equals() to compare objects in Java.
- == return true if two references are of the same object. The result of equals() method depends on overridden implementation.
- For comparing the content of two Strings use equals() instead of == equality operator.
public class StringEqualsTest{
public static void main(String []args){
String s1 = "string";
String s2 = "string";
String s3 = new String("string");
System.out.println(" == opearator result for s1 and s2 : " + (s1 == s2));
System.out.println(" == opearator result for s1 and s3 : " + (s1 == s3));
System.out.println(" equals() method result for s1 and s2 : " + s1.equals(s2));
System.out.println(" equals() method result for s1 and s3 : " + s1.equals(s3));
}
}
Output:
== opearator result for s1 and s2 : true
== opearator result for s1 and s3 : false
equals() method result for s1 and s2 : true
equals() method result for s1 and s3 : true
2.3. Call .equals() Method on Known String Constants Rather Than Unknown Variable
If you know some constants are fixed then use equals method on know constants rather than unknown variable. Some time variable may contain null and if you are calling equals method on null contains variable leads to null pointer exception.public class ConstantEqualsTest{
private static final String CONSTANT = "constant value";
public static void main(String []args){
processString("constant value");
}
private static void processString(String str){
if(CONSTANT.equals(str)){
System.out.println("CONSTANT.equals(string): "
+ CONSTANT.equals(str));
}
}
}
Output:
CONSTANT.equals(string): true
2.4. Prefer switch( ) Statement Instead of Multiple if-else-if
Java 1.7 introduces the switch statement for Strings. If there is the scenario to compare multiple strings then use switch over multiple if-else-if statements. Here is a comparison of the performance of these two approaches.
public class Test {
public static final String CONSTANT = "someConstant";
public static void main(String[] args) {
Test test = new Test();
long startTime = System.nanoTime();
test.convertStringToIntegerWithSwitch("FOUR");
long endTime = System.nanoTime();
System.out.println(String.format("String comparison with Switch took [%d] nano seconds.",(endTime-startTime)));
startTime = System.nanoTime();
test.convertStringToIntegerWithIf("FOUR");
endTime = System.nanoTime();
System.out.println(String.format("String comparison with If took [%d] nano seconds.",(endTime-startTime)));
}
private int convertStringToIntegerWithSwitch(String stringNumber) {
switch(stringNumber) {
case "ZERO" :
return 0;
case "ONE":
return 1;
case "TWO":
return 2;
case "THREE":
return 3;
default :
return -1;
}
}
private int convertStringToIntegerWithIf(String stringNumber) {
if("ZERO".equals(stringNumber)) {
return 0;
} else if("ONE".equals(stringNumber)) {
return 1;
} else if("TWO".equals(stringNumber)) {
return 2;
} else if("THREE".equals(stringNumber)) {
return 3;
} else {
return -1;
}
}
}
2.5. Use String.valueOf() Instead of toString()
If object needs to be converted to string then the result of obj.toString() and String.valueOf(obj) will be same but String.valueOf() is null safe, means it will never throw NullPointerException.
Test test = null;
// Below statement will not throw NPE
System.out.println(String.valueOf(test));
// Next statement will throw NPE
System.out.println(test.toString())
means if we are sure the object will never be null then we should always use toString() otherwise, String.valueOf() is preferable.
2.6. Use String Utility Classes
Prefer StringUtility classes from different popular libraries because these Utility classes are tested and well-known libraries.
I have created my own String Utility classes and have used in tons of projects.
You should refer these utility classes or methods:
You should refer these utility classes or methods:
2.7 Avoid Duplicate Literals
Code containing duplicate String literals can usually be improved by declaring the String as a constant field.
Example:
private void bar() {
String howdy= "Howdy"
buz(howdy);
buz(howdy);
}
private void buz(String x) {}
// Better
private static final String HOWDY = "Howdy";
private void bar() {
buz(HOWDY);
buz(HOWDY);
}
private void buz(String x) {}
Other Basic String Best Practices
Unnecessary Case Change
Using equalsIgnoreCase() is faster than using toUpperCase() or toLowerCase().equals()
Append Character With Char
Avoid concatenating characters as strings in StringBuffer/StringBuilder.append methods.
Example:
StringBuffer sb = new StringBuffer();
sb.append("a"); // avoid this
StringBuffer sb = new StringBuffer();
sb.append('a'); // use this instead
Consecutive Appends Should Reuse
Consecutive calls to StringBuffer/StringBuilder.append should be chained, reusing the target object. This can improve the performance by producing a smaller bytecode, reducing overhead and improving inlining. A complete analysis can be found here
Example:
String foo = " ";
StringBuffer buf = new StringBuffer();
buf.append("Hello"); // poor
buf.append(foo);
buf.append("World");
StringBuffer buf = new StringBuffer();
buf.append("Hello").append(foo).append("World"); // good
Avoid StringBuffer Field
StringBuffers/StringBuilders can grow considerably, and so may become a source of memory leaks if held within objects with long lifetimes.
Example:
public class Foo {
private StringBuffer buffer;
// potential memory leak as an instance variable;
}
Unnecessary Conversion Temporary
Avoid unnecessary temporaries when converting primitives to Strings.
Example:
public String convert(int x) {
// this wastes an object
String foo = new Integer(x).toString();
// this is better
return Integer.toString(x);
}
Let me know if you know any other best practices for Strings in Java.
Eclipse Tip - Use MessageFormatter
Do you prefer your strings concatenations 'printf' style? Eclipse can do it for you automatically!.
3. Conclusion
This post explained the best practices for String API. Learn more Java best practices on Java Best Practices Series. Let us know if you know any other best practices for String Handling in Java.Feel free to comment on this post and give us a suggestion or feedback.
4. Related Posts
- JUnit Framework Best Practices
- Java Naming Conventions
- Single Responsibility Principle
- Liskov's Substitution Principle
- Interface Segregation Principle
- Dependency Inversion Principle
- Open Closed Principle
- Oops principles in java
- Restful API Best Practices
- JSP Best Practices
- Guide to JDBC Best Practices
- Collection Best Practices
- String Best Practices in Java
- Exception Handling Best Practices
- Synchronization Best Practices
- Guide to JDBC Best Practices
- Serialization Best Practices
Free Spring Boot Tutorial | Full In-depth Course | Learn Spring Boot in 10 Hours
Watch this course on YouTube at Spring Boot Tutorial | Fee 10 Hours Full Course
Very helpful, productive and informative article. I highly recommend this article to everyone.
ReplyDeleteGreat and productive article for Java beginners to know String best practices.
ReplyDelete