String Operations with Java Streams – 用Java流进行字符串操作

最后修改: 2017年 2月 15日

1. Overview


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

Java 8引入了一个新的Stream API,使我们能够以声明的方式处理数据。

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.

在这篇快速文章中,我们将学习如何使用Stream API将一个逗号分隔的String分割成一个String列表,以及如何将一个String数组加入一个逗号分隔的String

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

我们还将看看如何使用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.

如果你想阅读更多关于Stream API的内容,请查看这篇文章

2. Joining Strings With the Stream API

2.用Stream API连接字符串

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

让我们使用Stream API来创建一个函数,将一个String数组连接成一个逗号分隔的String

public static String join(String[] arrayOfString){
    return Arrays.asList(arrayOfString)

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:

在某些情况下,我们可能想用一些固定的前缀和后缀来连接一个String。使用Stream API,我们可以通过以下方式实现。

public static String joinWithPrefixPostfix(String[] arrayOfString){
    return Arrays.asList(arrayOfString)

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

3.用Stream API拆分字符串

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

现在,让我们创建一个函数,使用Stream API将一个逗号分隔的字符串分割成字符串的列表。

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

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

也可以使用Stream API直接将字符串转换为字符列表。

public static List<Character> splitToListOfChar(String str) {
    return str.chars()
      .mapToObj(item -> (char) item)

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

4.用Stream API将StringArray转为Map

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)
	  .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:

请记住,为了避免编译错误,我们需要确保代码是使用Java 1.8编译的。要做到这一点,我们需要在pom.xml中添加以下插件。


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:


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:


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

    List<String> expectation = new ArrayList<>();

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

    assertEquals(result, expectation);

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


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.

Stream API为我们提供了复杂的数据处理技术。这种新的代码编写方式在多线程环境下的堆内存管理方面非常有效。

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