What is the purpose of String.strip() method of Java 11?

The purpose of the String.strip() method in Java 11 is to remove whitespaces from both the beginning and end of a string. This is very similar to the String.trim() method available in earlier versions of Java, but there is a key difference between them.

Here’s the difference:

  • String.strip(): Introduced in Java 11, strip() uses the unicode definition of whitespace. It removes not only space characters but also all other types of unicode-defined spaces, such as the thin space \u2009, etc.
  • String.trim(): Available from Java 1.0, trim() is more limited. It considers a whitespace to be any character whose ASCII value is less than or equal to 32 (a space, tab, newline, and a few other control characters).

Here are examples of how they work:

package org.kodejava.lang;

public class StringStripExample {
    public static void main(String[] args) {
        // String.strip()
        String first = " \u2009Hello  ";
        System.out.println(first.strip()); // Outputs "Hello"

        // String.trim()
        String second = " \u2009Hello  ";
        System.out.println(second.trim()); // Outputs "\u2009Hello"
    }
}

Output:

Hello
 Hello

Thus, strip() method is more comprehensive in removing different types of whitespace defined in Unicode, while trim() only removes ASCII control characters and spaces.

There are also String.stripLeading() and String.stripTrailing() methods that were introduced in Java 11, and they are similar to the strip() method, but they only remove the whitespace characters from either the beginning or the end of the string, respectively.

Here is what they do:

  • String.stripLeading(): This method removes any leading whitespace from the string. “Leading” in this context means any whitespace characters at the beginning of the string.
  • String.stripTrailing(): This method removes any trailing whitespace from the string. “Trailing” in this context means any whitespace characters at the end of the string.

Both stripLeading() and stripTrailing() use the Unicode definition of whitespace, the same as strip() method.

Here are examples of how they work:

package org.kodejava.lang;

public class StringStripLeadingTrailingExample {
    public static void main(String[] args) {
        // Strip leading whitespace
        String first = " \u2009Hello World  ";
        System.out.println(first.stripLeading());  // Outputs "Hello World  "

        // Strip trailing whitespace
        String second = " \u2009Hello World  ";
        System.out.println(second.stripTrailing()); // Outputs " \u2009Hello World"
    }
}

Output:

Hello World  
  Hello World

As demonstrated, stripLeading() removed the whitespace characters from the front of the string, and stripTrailing() removed the whitespace characters from the end of the string.

While \u00A0 is technically a type of whitespace (specifically, a non-breaking space or NBSP), it isn’t considered as such by the strip(), stripLeading(), and stripTrailing() methods, which follow the Character.isWhitespace(char) method’s definition of what constitutes a whitespace character.

According to the Java documentation, the Character.isWhitespace(char) method, which the strip() methods use, considers the following characters as whitespace:

  • ‘\t’ U+0009 HORIZONTAL TABULATION
  • ‘\n’ U+000A LINE FEED
  • ‘\u000B’ U+000B VERTICAL TABULATION
  • ‘\f’ U+000C FORM FEED
  • ‘\r’ U+000D CARRIAGE RETURN
  • ‘\u001C’ U+001C FILE SEPARATOR
  • ‘\u001D’ U+001D GROUP SEPARATOR
  • ‘\u001E’ U+001E RECORD SEPARATOR
  • ‘\u001F’ U+001F UNIT SEPARATOR
  • SPACE_SEPARATOR category types

The \u2009 (thin space) and \u0020 (space) are part of SPACE_SEPARATOR category according to Unicode standard and will be correctly stripped.

The \u00A0 (non-breaking space) is actually part of a different category called the NO-BREAK_SPACE and is not considered whitespace by Character.isWhitespace(char), so it won’t be stripped.

How do I use Map.of() factory method to create a map object?

In Java, the Map.of() factory method can be used to create an unmodifiable map of specified key-value pairs. This method is available in Java 9 and later versions.

Creating a map is a bit more complicated than creating lists or sets. Because we need to provide keys and values when creating a map. When using the Map.of() factory method we set the content of the map by alternating between the keys and values of the map.

Consider the following example:

package org.kodejava.util;

import java.util.Map;

public class MapOfExample {
    public static void main(String[] args) {
        Map<String, Integer> map = Map.of("John", 25, "Mary", 30, "Alice", 27, "Rosa", 22);

        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            System.out.println(entry.getKey() + " : " + entry.getValue());
        }
    }
}

Output:

Rosa : 22
Mary : 30
John : 25
Alice : 27

In the example above, the Map.of("John", 25, "Mary", 30, "Alice", 27, "Rosa", 22) statement creates an unmodifiable map with three key-value pairs. After the map is created, any attempt to modify the map (add, update or remove elements) will throw an UnsupportedOperationException.

Note that Map.of() doesn’t accept null keys or values. If a null key or value is provided, then a NullPointerException is thrown. Besides, if duplicate keys are provided, an IllegalArgumentException is thrown.

The Map.of() method is overloaded to accept up to 10 key-value pairs. If there are more than 10 pairs, you can use Map.ofEntries() factory method to create a map. This is how we use it:

Map<String, Integer> map = Map.ofEntries(
    Map.entry("John", 25),
    Map.entry("Mary", 30),
    Map.entry("Alice", 27),
    Map.entry("Bob", 32),
    // ...
);

for (Map.Entry<String, Integer> entry : map.entrySet()) {
    System.out.println(entry.getKey() + " : " + entry.getValue());
}

The Map.entry() is another factory method provided to create Map.Entry object.

How do I use Set.of() factory method to create a set object?

As with List.of(), in Java 9, the Set.of() factory method can be used to create an unmodifiable set of specified elements.

Here is a simple example:

package org.kodejava.util;

import java.util.Set;

public class SetOfExample {
    public static void main(String[] args) {
        Set<String> names = Set.of("Rosa", "John", "Mary", "Alice");

        for (String name : names) {
            System.out.println(name);
        }
    }
}

Output:

John
Rosa
Alice
Mary

In this example, the Set.of("Rosa", "John", "Mary", "Alice") statement creates an unmodifiable set of strings containing “Rosa”, “John”, “Mary”, and “Alice”. The resulting set is unmodifiable, so attempting to add, update, or remove elements from it will throw an UnsupportedOperationException.

If you try to create a Set by providing a duplicate elements, an IllegalArgumentException will be thrown. A Set is a type of collection container that cannot have duplicate values in it.

Note that the Set.of() method doesn’t accept null values. If you try to insert a null value, it will throw a NullPointerException. If you add a null value using the add() method UnsupportedOperationException will be thrown.

Set.of() is overloaded similarly to List.of(), allowing you to create a set with varying numbers of elements. The below examples demonstrate the use of Set.of() with different numbers of arguments:

Set<String> a = Set.of(); // An empty set
Set<String> b = Set.of("One"); // A set with one element
Set<String> c = Set.of("One", "Two"); // A set with two elements
// ...
Set<String> j = Set.of("One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"); // A set with ten elements

If you need to create a set with more than 10 elements, Set.of() offers an overloaded version that accepts an array or varargs:

Set<String> set = Set.of("One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven");

Remember that sets created with Set.of() are unmodifiable. Attempting to add, remove or change an element in these sets after their creation causes an UnsupportedOperationException.

Also, Set.of() doesn’t allow duplicate or null elements. If you pass duplicate or null values, it will throw IllegalArgumentException and NullPointerException respectively.

How do I use List.of() factory method to create a list object?

In Java, you can use the List.of() factory method to create an unmodifiable List consisting of specified elements. This method is available from Java 9 onwards.

Here is a simple example:

package org.kodejava.util;

import java.util.List;

public class ListOfExample {
    public static void main(String[] args) {
        List<String> names = List.of("Rosa", "John", "Mary", "Alice");

        for (String name : names) {
            System.out.println(name);
        }

        names.add("Bob"); // throws java.lang.UnsupportedOperationException
    }
}

In the code above, we have created a list of names including “Rosa”, “John”, “Mary”, and “Alice”. This newly created list is unmodifiable, so attempting to add, update, or remove elements from it will throw an UnsupportedOperationException.

There are several overloaded versions of the List.of() method that each accept different numbers of arguments. The versions range from no argument (which creates an empty list) to 10 explicit arguments of type E. Here’s an example:

List<String> a = List.of(); // An empty list
List<String> b = List.of("One"); // A list with one element
List<String> c = List.of("One", "Two"); // A list with two elements
// ...
List<String> j = List.of("One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"); // A list with ten elements

However, if we need to create a list with more than 10 elements, we have another overloaded version of List.of() method which accepts an array or varargs.

List<String> list = List.of("One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven");

Remember that these lists are unmodifiable. That means, if you try to modify the list (add, update, or remove elements) after they have been created, an UnsupportedOperationException will be thrown. Also, List.of() doesn’t allow null elements. If you pass null, it will throw UnsupportedOperationException.

How do I use Collectors.maxBy() method?

The Collectors.maxBy() method is used to find the maximum element from a stream based on a certain comparator. It returns an Optional which contains the maximum element according to the provided comparator, or an empty Optional if there are no elements in the stream.

Here’s a simple example where we have a list of integers, and we want to find the biggest integer:

package org.kodejava.stream;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class MaxByDemo {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);

        Optional<Integer> maxNumber = numbers.stream()
                .collect(Collectors.maxBy(Comparator.naturalOrder()));

        maxNumber.ifPresent(System.out::println);
    }
}

In this example:

  • We create a Stream from the list of integers.
  • We then use Collectors.maxBy(Comparator.naturalOrder()) to get the maximum number. Comparator.naturalOrder() is a shortcut for Comparator.comparing(Function.identity()).
  • Collectors.maxBy() returns an Optional because the stream could be empty.
  • We print the maximum number if it exists.

When you run this program, it will print “5” because 5 is the biggest number in the list.

Keep in mind that if the stream is empty, maxNumber will be an empty Optional, and nothing will be printed.