Java Top

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE

1. Introduction

String-based values and operations are quite common in everyday development, and any Java developer must be able to handle them.

In this tutorial, we'll provide a quick cheat sheet of common String operations.

Additionally, we'll shed some light on the differences between equals and “==” and between StringUtils#isBlank and #isEmpty.

2. Transforming a Char into a String

A char represents one character in Java. But in most cases, we need a String.

So let's start off with transforming chars into Strings:

String toStringWithConcatenation(final char c) {
    return String.valueOf(c);
}

3. Appending Strings

Another frequently needed operation is appending strings with other values, like a char:

String appendWithConcatenation(final String prefix, final char c) {
    return prefix + c;
}

We can append other basic types with a StringBuilder as well:

String appendWithStringBuilder(final String prefix, final char c) {
    return new StringBuilder(prefix).append(c).toString();
}

4. Getting a Character by Index

If we need to extract one character out of a string, the API provides everything we want:

char getCharacterByIndex(final String text, final int index) {
    return text.charAt(index);
}

Since a String uses a char[] as a backing data structure, the index starts at zero.

5. Handling ASCII Values

We can easily switch between a char and its numerical representation (ASCII) by casting:

int asciiValue(final char character) {
    return (int) character;
}

char fromAsciiValue(final int value) {
    Assert.isTrue(value >= 0 && value < 65536, "value is not a valid character");
    return (char) value;
}

Of course, since an int is 4 unsigned bytes and a char is 2 unsigned bytes, we need to check to make sure that we are working with legal character values.

6. Removing All Whitespace

Sometimes we need to get rid of some characters, most commonly whitespace. A good way is to use the replaceAll method with a regular expression:

String removeWhiteSpace(final String text) {
    return text.replaceAll("\\s+", "");
}

7. Joining Collections to a String

Another common use case is when we have some kind of Collection and want to create a string out of it:

<T> String fromCollection(final Collection<T> collection) { 
   return collection.stream().map(Objects::toString).collect(Collectors.joining(", "));
}

Notice that the Collectors.joining allows specifying the prefix or the suffix.

8. Splitting a String

Or on the other hand, we can split a string by a delimiter using the split method:

String[] splitByRegExPipe(final String text) {
   return text.split("\\|");
}

Again, we're using a regular expression here, this time to split by a pipe. Since we want to use a special character, we have to escape it.

Another possibility is to use the Pattern class:

String[] splitByPatternPipe(final String text) {
    return text.split(Pattern.quote("|"));
}

9. Processing All Characters as a Stream

In the case of detailed processing, we can transform a string to an IntStream:

IntStream getStream(final String text) {
    return text.chars();
}

10. Reference Equality and Value Equality

Although strings look like a primitive type, they are not.

Therefore, we have to distinguish between reference equality and value equality. Reference equality always implies value equality, but in general not the other way around.  The first, we check with the ‘==' operation and the latter, with the equals method:

@Test
public void whenUsingEquals_thenWeCheckForTheSameValue() {
    assertTrue("Values are equal", new String("Test").equals("Test"));
}

@Test
public void whenUsingEqualsSign_thenWeCheckForReferenceEquality() {
    assertFalse("References are not equal", new String("Test") == "Test");
}

Notice that literals are interned in the string pool. Therefore the compiler can at times optimize them to the same reference:

@Test
public void whenTheCompileCanBuildUpAString_thenWeGetTheSameReference() {
    assertTrue("Literals are concatenated by the compiler", "Test" == "Te"+"st");
}

11. Blank String vs. Empty String

There is a subtle difference between isBlank and isEmpty.

A string is empty if it's null or has length zero. Whereas a string is blank if it's null or contains only whitespace characters:

@Test
public void whenUsingIsEmpty_thenWeCheckForNullorLengthZero() {
    assertTrue("null is empty", isEmpty(null));
    assertTrue("nothing is empty", isEmpty(""));
    assertFalse("whitespace is not empty", isEmpty(" "));
    assertFalse("whitespace is not empty", isEmpty("\n"));
    assertFalse("whitespace is not empty", isEmpty("\t"));
    assertFalse("text is not empty", isEmpty("Anything!"));
}

@Test
public void whenUsingIsBlank_thenWeCheckForNullorOnlyContainingWhitespace() {
    assertTrue("null is blank", isBlank(null));
    assertTrue("nothing is blank", isBlank(""));
    assertTrue("whitespace is blank", isBlank("\t\t \t\n\r"));
    assertFalse("test is not blank", isBlank("Anything!"));
}

12. Conclusion

Strings are a core type in all kinds of applications. In this tutorial, we learned some key operations in common scenarios.

Furthermore, we gave directions to more detailed references.

Finally, the full code with all examples is available in our GitHub repository.

Java bottom

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE
Comments are closed on this article!