1. 概述
Java 8 引入了一个新的流(Stream) API,它允许我们以声明式的方式处理数据。
在这篇简短的文章中,我们将学习如何使用流(Stream) API 将逗号分隔的字符串分解成字符串列表,以及如何将字符串数组合并成一个逗号分隔的字符串。我们还将探讨如何使用流(Stream) API 将字符串数组转换为映射。
在大多数情况下,我们都需要遍历Java集合并根据某些过滤逻辑对集合进行过滤。传统上,对于这种场景,我们会使用大量循环和if-else语句来获取期望的结果。
如果你想了解更多关于流(Stream) API的内容,请参阅这篇文章。
2. 使用流(Stream) API 合并字符串
让我们使用流(Stream) API 来创建一个函数,将字符串数组合并成一个逗号分隔的字符串:
public static String join(String[] arrayOfString){
return Arrays.asList(arrayOfString)
.stream()
//.map(...)
.collect(Collectors.joining(","));
}
这里需要注意:
stream()
函数将任何集合转换为数据流。map()
函数用于处理数据。- 还有一个名为
filter()
的函数,我们可以在此处包含过滤条件。
有些情况下,我们可能希望在字符串前后添加固定的前缀和后缀。使用流(Stream) API,我们可以这样做:
public static String joinWithPrefixPostfix(String[] arrayOfString){
return Arrays.asList(arrayOfString)
.stream()
//.map(...)
.collect(Collectors.joining(",","[","]"));
}
如Collectors.joining()
方法所示,我们声明了前缀为['
和后缀为']
;因此生成的字符串将以[……]
格式创建。
3. 使用流(Stream) API 分割字符串
现在,让我们创建一个函数,使用流(Stream) API 将逗号分隔的字符串分解成字符串列表:
public static List<String> split(String str){
return Stream.of(str.split(","))
.map (elem -> new String(elem))
.collect(Collectors.toList());
}
同样,我们也可以直接使用流(Stream) API 将字符串转换为字符列表:
public static List<Character> splitToListOfChar(String str) {
return str.chars()
.mapToObj(item -> (char) item)
.collect(Collectors.toList());
}
这里的一个有趣事实是,chars()
方法将字符串转换为整数流,其中每个整数值表示每个字符序列的ASCII值。这就是为什么我们在mapToObj()
方法中需要显式地将映射对象类型转换。
4. 使用流(Stream) API 将字符串数组转换为映射
我们还可以使用split
和Collectors.toMap
将字符串数组转换为映射,前提是数组中的每个元素都包含由分隔符连接的键值对:
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]));
}
这里,":"
是字符串数组中所有元素的键值分隔符。
请记住,为了避免编译错误,我们需要确保代码是使用Java 1.8编译的。为此,我们需要在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. 测试
既然我们已经创建了函数,让我们编写测试用例来验证结果。
首先,让我们测试我们的简单合并方法:
@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);
}
接下来,让我们创建另一个测试用例来测试简单的分割功能:
@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);
}
最后,让我们测试我们的字符串数组到映射的功能:
@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);
}
同样,我们需要为其他测试用例创建相应的代码。
6. 总结
流(Stream) API 提供了高级的数据处理技术。这种新的编程方式在多线程环境中对堆内存管理非常高效。
一如既往,完整的源代码可在GitHub上找到。