String Operations with Java Streams

1. Overview

Java 8 has introduced a new Stream API that lets us process data in a declarative manner.

In this quick article, we would learn how to use the Stream API to split a comma-separated String into a list of Strings and how to join a String array into a comma-separated String.

We’ll also look at how to convert a string array to map using Stream API.

Nearly all of the time we face situations, where we need to iterate some Java Collections and filter the Collection based on some filtering logic. In a traditional approach for this type of situation, we would use lots of loops and if-else operations to get the desired result.

If you want to read more about the Stream API, check this article.

2. Joining Strings With the Stream API

Let’s use the Stream API to create a function which would join a String array into a comma-separated String:

public static String join(String[] arrayOfString){
    return Arrays.asList(arrayOfString)
      .stream()
      //.map(...)
      .collect(Collectors.joining(","));
}

Points to note here:

  • The stream() function converts any Collection into a stream of data
  • map() function is used to process the data
  • There is also another function, named filter(), where we can include filtering criteria

There can be scenarios, where we may want to join a String with some fixed prefix and postfix. With the Stream API we can do that in the following way:

public static String joinWithPrefixPostfix(String[] arrayOfString){
    return Arrays.asList(arrayOfString)
      .stream()
      //.map(...)
      .collect(Collectors.joining(",","[","]"));
}

As we can see in the Collectors.joining() method, we are declaring our prefix as ‘[‘ and postfix as ‘]’; hence the generated String will be created with declared […..] format.

3. Splitting Strings With Stream API

Now, let’s create a function, which would split a comma separated String into a list of String using Stream API:

public static List<String> split(String str){
    return Stream.of(str.split(","))
      .map (elem -> new String(elem))
      .collect(Collectors.toList());
}

It’s also possible to directly convert a String to a Character list using the Stream API:

public static List<Character> splitToListOfChar(String str) {
    return str.chars()
      .mapToObj(item -> (char) item)
      .collect(Collectors.toList());
}

One interesting fact to note here is that the chars() method converts the String into a stream of Integer where each Integer value denotes the ASCII value of each and every Char sequence. That’s why we need to explicitly typecast the mapper object in the mapToObj() method.

4. String Array to Map With Stream API

We can also convert a String array to map using split and Collectors.toMap, provided each item in the array contains a key-value entity concatenated by a separator:

public static Map<String, String> arrayToMap(String[] arrayOfString) {
	return Arrays.asList(arrayOfString)
	  .stream()
	  .map(str -> str.split(":"))
	  .collect(toMap(str -> str[0], str -> str[1]));
}

Here, “:” is the key-value separator for all the elements in String array.

Please remember that in order to avoid compilation error, we need to ensure that code is compiled using Java 1.8. To do this, we need to add the following plugin in the pom.xml:

<build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.3</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
    </plugins>        
</build>

5. Testing

Since we are done creating the functions, let’s create test cases to verify the outcome.

First, let’s test our simple joining method:

@Test
public void givenArray_transformedToStream_convertToString() {
    String[] programmingLanguages = {"java", "python", "nodejs", "ruby"};
    String expectation = "java,python,nodejs,ruby";

    String result  = JoinerSplitter.join(programmingLanguages);
    assertEquals(result, expectation);
}

Next, let’s create another one to test our simple splitting functionality:

@Test
public void givenString_transformedToStream_convertToList() {
    String programmingLanguages = "java,python,nodejs,ruby";

    List<String> expectation = new ArrayList<>();
    expectation.add("java");
    expectation.add("python");
    expectation.add("nodejs");
    expectation.add("ruby");

    List<String> result  = JoinerSplitter.split(programmingLanguages);

    assertEquals(result, expectation);
}

Finally, let’s test our String array to map functionality:

@Test
public void givenStringArray_transformedToStream_convertToMap() {

    String[] programming_languages = new String[] {"language:java","os:linux","editor:emacs"};
    
    Map<String,String> expectation=new HashMap<>();
    expectation.put("language", "java");
    expectation.put("os", "linux");
    expectation.put("editor", "emacs");
    
    Map<String, String> result = JoinerSplitter.arrayToMap(programming_languages);
    assertEquals(result, expectation);
    
}

In the same way, we need to create the rest of the test cases.

6. Conclusion

Stream API provides us with sophisticated data processing techniques. This new way of writing code is very efficient in terms of heap memory management in a multi-threaded environment.

Like always, the full source code is available over on Github.

Related posts:

Java Program to Implement Hash Tables Chaining with Binary Trees
Spring Data JPA Delete and Relationships
Java Program to Construct a Random Graph by the Method of Random Edge Selection
Truyền giá trị và tham chiếu trong java
Java Program to Implement Treap
Java Program to find the maximum subarray sum O(n^2) time(naive method)
Java Program to Check if a Given Set of Three Points Lie on a Single Line or Not
Java Program to Implement LinkedList API
Toán tử instanceof trong java
HttpClient 4 – Follow Redirects for POST
Java Program to implement Array Deque
Spring Boot - Logging
Spring 5 Testing with @EnabledIf Annotation
Spring’s RequestBody and ResponseBody Annotations
Posting with HttpClient
Java Perform to a 2D FFT Inplace Given a Complex 2D Array
Java Program to Implement vector
Java Program to Perform LU Decomposition of any Matrix
Spring Data Reactive Repositories with MongoDB
Java Program to Create a Random Graph Using Random Edge Generation
Converting Between Byte Arrays and Hexadecimal Strings in Java
Intro to the Jackson ObjectMapper
Java Program to Perform String Matching Using String Library
Spring MVC Content Negotiation
Java Program to Implement Naor-Reingold Pseudo Random Function
Tạo ứng dụng Java RESTful Client với thư viện OkHttp
Jackson Unmarshalling JSON with Unknown Properties
Using a Mutex Object in Java
Java Program to Generate All Possible Combinations of a Given List of Numbers
Lớp Collectors trong Java 8
Java Program to Represent Graph Using Incidence Matrix
Documenting a Spring REST API Using OpenAPI 3.0