Guide to Apache Commons' StringUtils Class in Java

Introduction

The Apache Commons library provides many new interfaces, implementations and classes that expand on the core Java Framework. It's one of the top third-party libraries and is present in many projects.

In this article, we've compiled a Guide to Apache Commons' StringUtils class, which provides some very good utilities and tools for working with Strings, expanding on the functionality of the core class - java.lang.String.

StringUtils is probably the most used class from Apache Commons, and contains various utility and convenience methods that allow developers to avoid writing boilerplate or just plain cumbersome code for basic operations.

Why use StringUtils instead of String Methods?

Many of the methods in the StringUtils class have their equivalents in the java.lang.String, but those found in StringUtils are null-safe. This means that NullPointerExceptions aren't thrown in cases where you might not expect them to.

As mentioned earlier, Apache Commons contains a number of methods, and we'll be covering some of the most used ones:

Getting Started with Apache Commons

To be able to use the Apache Commons library, we first need to import it into our project.

If you're using Maven, import the latest dependency to your pom.xml file:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.11</version>
</dependency>

Alternatively, if you're using Gradle:

compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.11'

With the commons-lang3 dependency in our project, we can move on to discussing some of the most used methods from StringUtils. Let's get started!

Comparing Strings with Apache Commons

Comparing Strings, checking if they're empty, or blank, or simply checking if they're equal are pretty common operations.

Let's start off with some comparison-related methods.

StringUtils.isEmpty() and StringUtils.isBlank()

These two methods are pretty self explanatory - they're both used to check if a String contains any text. Both of these return true if the String is indeed empty. Additionally, isBlank() will also return true if a String contains only whitespaces.

They also have their inverse methods: isNotEmpty() and isNotBlank().

Let's see how we can use isEmpty() alongside it's counterpart java.lang.String.isEmpty(), as well as isBlank():

String nullString = null;
String emptyString = "";
String blankString = "\n \t   \n";

if(!nullString.isEmpty()) {
    System.out.println("nullString isn't null");
}

if(StringUtils.isEmpty(emptyString)) {
    System.out.println("emptyString is empty");
}

if(StringUtils.isBlank(blankString)) {
    System.out.println("blankString is blank");
}

We've got three Strings here. One points to null, the second one isn't null, but doesn't have any contents (it's empty), and the third one isn't empty, but will produce a blank result if printed.

Running this code results in:

Exception in thread "main" java.lang.NullPointerException

The isEmpty() method that's built-in to java.lang.String isn't null-safe. It'll throw a NullPointerException if you try to check if it's empty, since you're calling a method on a null reference. You'll have to check if the reference is null beforehand:

String nullString = null;
String emptyString = "";
String blankString = "\n \t   \n";

if (nullString != null && !nullString.isEmpty()) {
    System.out.println("nullString isn't null");
}

if (StringUtils.isEmpty(emptyString)) {
    System.out.println("emptyString is empty");
}

if (StringUtils.isBlank(blankString)) {
    System.out.println("blankString is blank");
}

Now, this results in:

emptyString is empty
blankString is blank

And if we test these methods out on the nullString:

if (StringUtils.isEmpty(nullString)) {
    System.out.println("emptyString is empty");
}

if (StringUtils.isBlank(nullString)) {
    System.out.println("blankString is blank");
}

This results in:

emptyString is empty
blankString is blank

StringUtils methods are null-safe, and produce the result you'd expect these methods to return upon encountering a null reference.

StringUtils.equals()

This one does exactly what you think it does - compares two Strings and returns true, if they're identical or both references point to null, but do keep in mind that this method is case-sensitive.

Let's see how this method works:

System.out.println(StringUtils.equals(null, null));
System.out.println(StringUtils.equals(null, "some string"));
System.out.println(StringUtils.equals("some string", null));
System.out.println(StringUtils.equals("some string", "some string"));
System.out.println(StringUtils.equals("some other string", "some string"));

This will output:

true
false
false
true
false

For the sake of comparing the equals() method from StringUtils to the java.lang.String.equals(), let's test them out:

String nullString = null;

System.out.println(StringUtils.equals(nullString, null));
System.out.println(StringUtils.equals(nullString, "string"));

System.out.println(nullString.equals(null));
System.out.println(nullString.equals("string"));

This results in:

true
false
Exception in thread "main" java.lang.NullPointerException

Again, invoking a method on a null reference results in a NullPointerException, we'd have to check if the reference variable is null before using it.

StringUtils.compare()

The declaration of this method is as follows:

public static int compare(CharSequence str1, CharSequence str2)

This method compares two Strings lexicographically, the same way java.lang.String.compareTo() does, returning:

  • 0 if str1 is equal to str2 (or both are null)
  • A value less than 0 if str1 is less than str2
  • A value greater than 0 if str1 is greater than str2

In this article we won't be discussing what exactly comparing two Strings lexicographically means, so if you're interested on reading more about that, check this link.

Now, let's see how we can use it in our program:

System.out.println(StringUtils.compare(null, null));
System.out.println(StringUtils.compare(null , "a"));
System.out.println(StringUtils.compare("a", null));
System.out.println(StringUtils.compare("a", "A"));
System.out.println(StringUtils.compare("a", "a"));

This will in turn output:

0
-1
1
32
0

Note: a null value is considered less than a non-null value. Two null values are considered equal.

Indexing Search Sequences with Apache Commons

Now, let's take a look at a group of methods that deal with index-checks, in of course, a null-safe way. All of these methods have multiple overloaded variants, but the most general ones are:

public static int indexOf(CharSequence seq, CharSequence searchSeq)
public static int lastIndexOf(CharSequence seq, CharSequence searchSeq)
public static boolean contains(CharSequence seq, CharSequence searchSeq)

There is one thing they all have in common: they all use their non-null safe variants from java.lang.String if it's possible to do so. Let's explain this in a bit more detail.

StringUtils.indexOf()

This method, much like the built-in one, will search for the index of the first appearance of a sequence within another sequence. If the built-in java.lang.String.indexOf() method doesn't produce a NullPointerException, it'll be used. If not, Apache Commons' implementation takes over.

The return value is the first index found, or -1 if there's either no match or the input string is null.

Let's write some code now:

String s = "Java is a general-purpose programming language";

System.out.println(StringUtils.indexOf(null, "a"));
System.out.println(StringUtils.indexOf(s, "general"));
System.out.println(StringUtils.indexOf(s, "l"));
System.out.println(StringUtils.indexOf(s, "lan"));

Running the code above will result in the following output:

-1
10
16
38

StringUtils.lastIndexOf()

The lastIndexOf() method works in much the same way indexOf() works, but it returns the last occurrence, not the first of the search sequence.

Let's run the same code from before:

String s = "Java is a general-purpose programming language";

System.out.println(StringUtils.lastIndexOf(null, "a"));
System.out.println(StringUtils.lastIndexOf(s, "general"));
System.out.println(StringUtils.lastIndexOf(s, "l"));
System.out.println(StringUtils.lastIndexOf(s, "lan"));

Running the code above will result in the following output:

Free eBook: Git Essentials

Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!

-1
10
38
38

Check if String Contains Another String with Apache Commons

StringUtils.contains()

The contains() method returns true or false based on whether a search sequence is contained within another sequence or not.

If successful, this method also uses the java.lang.String.indexOf(String). In the case of null as input, false is returned:

String s = "Java is a general-purpose programming language";

System.out.println(StringUtils.contains(null, "a"));
System.out.println(StringUtils.contains(s, "Java"));
System.out.println(StringUtils.contains(s, "Python"));
System.out.println(StringUtils.contains(s, "pRoGrAmMinG"));

The method, of course, if case-sensitive, so the last call will also return false:

false
true
false
false

StringUtils.containsIgnoreCase()

The containsIgnoreCase() method works in the same way the contains() method does, but isn't case-sensitive:

String s = "Java is a general-purpose programming language";

System.out.println(StringUtils.containsIgnoreCase(null, "a"));
System.out.println(StringUtils.containsIgnoreCase(s, "Java"));
System.out.println(StringUtils.containsIgnoreCase(s, "Python"));
System.out.println(StringUtils.containsIgnoreCase(s, "pRoGrAmMinG"));

This results in:

false
true
false
true

StringUtils.containsAny()

The containsAny() method check accepts variable arguments, or “vararg”, besides the String we're searching in. It return true if the searched sequence contains any elements from the passed arguments:

String s = "Java is a general-purpose programming language";

System.out.println(StringUtils.containsAny(s, "general", "python", "something", "javascript"));

This results in:

true

This method is also case-sensitive, so make sure to keep that in mind.

StringUtils.containsNone()

Instead of making edge-cases with the previous method, you can simply use containsNone() if you'd like to make sure a string doesn't contain any of the elements you passed as the variable arguments:

String s = "Java is a general-purpose programming language";

System.out.println(StringUtils.containsNone(s, "general", "python", "something", "javascript"));

This results in:

false

StringUtils.containsOnly()

Or, if you'd like to check if a String contains only the contents you predefined, you can use the containsOnly() method:

String s = "Java";

System.out.println(StringUtils.containsOnly(s, "Java"));

This results in:

true

Apache Commons Substring Methods

StringUtils.substring()

Between many of the available overloaded variants of this method, we'll be discussing two of them:

  1. substring(String str, int start)
  2. substring(String str, int start, int end)

This method returns a substring beginning at the start going to the end of the String, or the end index.

We can also use a negative number for the start parameter, which will give us a substring that starts n characters from the end of the String.

If there's a null input, the returned value will simply be null.

Let's see how we can use it:

System.out.println(StringUtils.substring("a random string", 4, 8));
System.out.println(StringUtils.substring("a random string", -7));
System.out.println(StringUtils.substring(null, 5));

Running the code above gives us:

ndom
 string
null

StringUtils.split()

Provided with a String and a separator character, this method will split the String and place it into an array.

The elements of the resulting array are substrings that are delimited by separators in the original String. The separator isn't included in the final array after the split.

Like with the other methods in the StringUtils, it returns null if the input is null.

Let's look at some code and how this method works:

String csvString = "Id, Name, Age, Location";
        
System.out.println(Arrays.toString(StringUtils.split(csvString, ',')));
System.out.println(Arrays.toString(StringUtils.split(null, '.')));
System.out.println(Arrays.toString(StringUtils.split("", '.')));

After running the code, we get:

[Id,  Name,  Age,  Location]
null
[]

StringUtils.join()

This method represents the direct opposite of the split() method.

After splitting a String with a separator character, we can just as easily join it with the join() method, by providing a list or an array of elements. It returns a String created gluing the provided elements together using the separator. If the input is null, the method returns null.

Let's look at this one basic example:

String csvString = "Id, Name, Age, Location";
        
String[] myStr =  StringUtils.split(csvString, ',');
System.out.println(StringUtils.join(myStr, ';'));

Running the code above gives us:

Id; Name; Age; Location

StringUtils.remove()

There are two variants of this method we want to look at:

public static String remove(String str, char remove)
public static String remove(String str, String remove)

They both do the same thing, with an exception that the second one removes every occurrence of a substring, while the first removes every occurrence of a character from the given String str.

If the input is null, the method returns null.

For this one, we'll split the examples in two separate blocks of code, because it can be a little difficult to differentiate them on a first-look basis. Let's start with remove(String str, char remove):

System.out.println(StringUtils.remove(null, 'a'));
System.out.println(StringUtils.remove("", 'a'));
System.out.println(StringUtils.remove("queued", 'u'));

System.out.println(StringUtils.remove(null, "abc"));
System.out.println(StringUtils.remove("", "abc"));
System.out.println(StringUtils.remove("abc", null));
System.out.println(StringUtils.remove("queued", "ue"));

Let's run this and see what it produces:

null // Returned null
     // Removed 'a' from ""
qeed // Removed 'u' characters
null // Returned null
     // Removed "abc" from ""
abc  // Removed null from "abc"
qd   // Removed "ue" from "queued"

We should note one thing here as it can easily be overlooked: when the remove parameter has a null value, the source string is returned.

StringUtils.replace()

Like most of the methods we've covered, this one is also very self-explanatory - it searches for a String within a String, finds it if it exists, and replaces all of its occurrences with a new String.

The declaration of this method is as follows:

public static String replace(String text, String searchString, String replacement)

If the searchString is not found within text, nothing happens, and our text stays the same. Following the same logic, if text is null, this method returns null.

If either of searchString or replacement have the value of null, the method returns its source, that is text.

Let's try this method out:

String string = "a simple sentence";
System.out.println(StringUtils.replace(string, "simple", "complicated"));

This will result in:

a complicated sentence

StringUtils.countMatches()

countMatches() counts how many times a specified character (or a substring) appears within the given String. A null or an empty input returns 0.

Let's see how this works in code:

String string = "I'm blue Da ba dee da ba di, Da ba dee da ba di";

System.out.println(StringUtils.countMatches(null, 'd'));
System.out.println(StringUtils.countMatches(string, 'd'));

System.out.println(StringUtils.countMatches(null, "da"));
System.out.println(StringUtils.countMatches(string, "da"));

Running the code above gives us:

0
6
0
2

Conclusion

In this article we've covered some of the most used and known methods within the Apache Commons' StringUtils class.

The methods found in the StringUtils class are null-safe, and provide basic, as well as extended functionality to the built-in string methods.

Last Updated: September 27th, 2023
Was this article helpful?

Improve your dev skills!

Get tutorials, guides, and dev jobs in your inbox.

No spam ever. Unsubscribe at any time. Read our Privacy Policy.

© 2013-2024 Stack Abuse. All rights reserved.

AboutDisclosurePrivacyTerms