Part 5 of 16

New String Methods (Java 11): isBlank, lines, strip, repeat

New String Methods in Java 11

Java 11 added six new instance methods to java.lang.String. None require any imports — they are part of the standard String class.

MethodReturnsDescription
isBlank()booleanTrue if string is empty or contains only whitespace
lines()Stream<String>Stream of lines split by line terminators
strip()StringRemoves leading and trailing Unicode whitespace
stripLeading()StringRemoves leading Unicode whitespace only
stripTrailing()StringRemoves trailing Unicode whitespace only
repeat(int n)StringReturns the string repeated n times

isBlank()

Returns true if the string is empty or contains only whitespace characters as defined by Character.isWhitespace().

"".isBlank()         // true
"  ".isBlank()       // true
"\t\n".isBlank()     // true
"hello".isBlank()    // false
"  hi  ".isBlank()   // false

isBlank() vs isEmpty()

isEmpty() only returns true for a zero-length string. isBlank() covers whitespace-only strings too:

" ".isEmpty()    // false — length is 1
" ".isBlank()    // true  — contains only whitespace

isBlank() vs trim().isEmpty()

trim() only strips ASCII control characters (code points 0–32). isBlank() uses Character.isWhitespace(), which covers all Unicode whitespace including non-breaking space, ideographic space, and other Unicode whitespace code points.

// Non-breaking space (U+00A0)
String nbsp = " ";
nbsp.trim().isEmpty()   // false — trim() doesn't strip non-breaking space
nbsp.isBlank()          // true  — isBlank() recognises it as whitespace

Common use cases

// Filter out blank lines from a list
List<String> lines = Arrays.asList("hello", "  ", "", "world", "\t");
var nonBlank = lines.stream()
    .filter(Predicate.not(String::isBlank))
    .collect(Collectors.toList());
// ["hello", "world"]

// Validate form input
if (userInput.isBlank()) {
    throw new IllegalArgumentException("Input must not be blank");
}

lines()

Returns a Stream<String> of lines extracted from the string, split on line terminators: \n, \r, \r\n.

"line1\nline2\nline3".lines().forEach(System.out::println);
// line1
// line2
// line3

"line1\r\nline2\r\n".lines().count()   // 2 — trailing terminator does NOT produce an empty line

lines() vs split("\n")

Featurelines()split("\\n")
Handles \r\nYesNo (produces \r at end of line)
Handles \r aloneYesNo
Trailing terminatorIgnoredProduces empty string
ReturnsStream<String>String[]
"a\r\nb".lines().collect(Collectors.toList())    // ["a", "b"]
"a\r\nb".split("\\n")                           // ["a\r", "b"] — note the \r

Common use cases

// Count non-blank lines in a file
long count = Files.readString(Path.of("src/Main.java"))
    .lines()
    .filter(Predicate.not(String::isBlank))
    .count();

// Parse a CSV file read into a single string
var csvContent = """
    name,age,city
    Alice,30,London
    Bob,25,Paris
    """;

csvContent.lines()
    .skip(1)  // skip header
    .map(line -> line.split(","))
    .forEach(fields ->
        System.out.printf("Name: %s, Age: %s%n", fields[0], fields[1]));

// Build a line-numbered source view
var sourceFile = Files.readString(Path.of("Main.java"));
var numbered = new AtomicInteger(0);
sourceFile.lines()
    .map(line -> String.format("%4d  %s", numbered.incrementAndGet(), line))
    .forEach(System.out::println);

strip(), stripLeading(), stripTrailing()

These methods remove Unicode whitespace from a string — using Character.isWhitespace() rather than the narrower ASCII-range check that trim() uses.

"  hello  ".strip()           // "hello"
"  hello  ".stripLeading()    // "hello  "
"  hello  ".stripTrailing()   // "  hello"

strip() vs trim()

trim() removes characters with code point ≤ 32 (ASCII control characters and space). strip() uses the Unicode-aware Character.isWhitespace() definition:

// Non-breaking space (U+00A0) — common in copy-paste from web content
String text = " hello ";
text.trim()           // " hello " — unchanged; trim() doesn't touch U+00A0
text.strip()          // "hello" — strip() recognises U+00A0 as whitespace

// Thin space (U+2009)
String thin = " hello ";
thin.trim()           // " hello " — unchanged
thin.strip()          // "hello"

When to use which

  • strip() — default choice for user-facing string sanitisation; handles all Unicode whitespace.
  • trim() — use only when you specifically want ASCII-only stripping and need backward compatibility.
  • stripLeading() — useful when preserving indentation on the right but removing leading whitespace.
  • stripTrailing() — common for removing trailing newlines or spaces from log lines.

Common use cases

// Sanitise HTTP header values
String headerValue = "  Bearer eyJhbGci...  ";
String token = headerValue.strip();

// Remove trailing newline from shell command output
String cmdOutput = executeCommand("git rev-parse HEAD");
String commitHash = cmdOutput.stripTrailing();

// Parse indented YAML-like config
String config = """
    server:
      port: 8080
      host: localhost
    """;
config.lines()
    .map(String::strip)
    .filter(Predicate.not(String::isBlank))
    .forEach(System.out::println);

repeat(int n)

Returns the string concatenated with itself n times.

"ab".repeat(3)    // "ababab"
"*".repeat(10)    // "**********"
"".repeat(100)    // ""
"x".repeat(0)     // ""

Throws IllegalArgumentException if n < 0.

repeat() vs StringBuilder loop

repeat() is internally optimised — it uses array copying rather than repeated string concatenation, making it significantly faster for large n:

// Before Java 11 — O(n²) string concatenation
String dashes = "";
for (int i = 0; i < 80; i++) {
    dashes += "-";
}

// Java 11 — O(n) array copy
String dashes = "-".repeat(80);

Common use cases

// Formatting: print a header with separator lines
String title = "Report Summary";
String separator = "-".repeat(title.length());
System.out.println(separator);
System.out.println(title);
System.out.println(separator);
// --------------
// Report Summary
// --------------

// Pad strings to a fixed width
String value = "42";
int width = 8;
String padded = " ".repeat(Math.max(0, width - value.length())) + value;
// "      42"

// Build test data
String csvRow = "field1,field2,field3";
String csv = (csvRow + "\n").repeat(1000);  // 1000 identical rows

// Create visual progress indicators
int progress = 65;
String bar = "[" + "#".repeat(progress / 10) + " ".repeat(10 - progress / 10) + "]";
// [######    ]

Predicate.not() — A Companion Utility (Java 11)

Predicate.not() is not a String method, but it was added in Java 11 and pairs naturally with the new String methods for stream filtering:

// Java 8 style — requires lambda wrapper
list.stream().filter(s -> !s.isBlank())

// Java 11 style — using Predicate.not()
list.stream().filter(Predicate.not(String::isBlank))

Predicate.not(pred) returns a predicate that is the logical negation of pred.


Complete Example: Parsing a Configuration Block

import java.util.*;
import java.util.function.*;
import java.util.stream.*;

public class ConfigParser {

    public static Map<String, String> parse(String configText) {
        return configText.lines()
            .map(String::strip)                          // remove leading/trailing whitespace
            .filter(Predicate.not(String::isBlank))      // skip blank lines
            .filter(line -> !line.startsWith("#"))       // skip comments
            .map(line -> line.split("=", 2))
            .filter(parts -> parts.length == 2)
            .collect(Collectors.toMap(
                parts -> parts[0].strip(),
                parts -> parts[1].strip()
            ));
    }

    public static void main(String[] args) {
        var config = """
            # Application configuration
            server.port = 8080
            server.host = localhost

            database.url  =  jdbc:postgresql://localhost/mydb
            database.pool = 10

            # End of config
            """;

        var parsed = parse(config);
        parsed.forEach((k, v) -> System.out.printf("%s -> %s%n", k, v));
    }
}
// server.port -> 8080
// server.host -> localhost
// database.url -> jdbc:postgresql://localhost/mydb
// database.pool -> 10

What’s Next

Next: Collection Factory Methods (JEP 269): Immutable List, Set, and Map