1. 概述
在这个快速教程中,我们将学习如何在Java中连接和拆分数组(Arrays)和集合(Collections),充分利用新的流(Stream)支持。
2. 连接两个数组
首先,我们使用Stream.concat
来连接两个数组:
@Test
public void whenJoiningTwoArrays_thenJoined() {
String[] animals1 = new String[] { "Dog", "Cat" };
String[] animals2 = new String[] { "Bird", "Cow" };
String[] result = Stream.concat(
Arrays.stream(animals1), Arrays.stream(animals2)).toArray(String[]::new);
assertArrayEquals(result, new String[] { "Dog", "Cat", "Bird", "Cow" });
}
3. 连接两个集合
接着,让我们用两个集合做同样的操作:
@Test
public void whenJoiningTwoCollections_thenJoined() {
Collection<String> collection1 = Arrays.asList("Dog", "Cat");
Collection<String> collection2 = Arrays.asList("Bird", "Cow", "Moose");
Collection<String> result = Stream.concat(
collection1.stream(), collection2.stream())
.collect(Collectors.toList());
assertTrue(result.equals(Arrays.asList("Dog", "Cat", "Bird", "Cow", "Moose")));
}
4. 过滤后连接两个集合
现在,让我们过滤掉大于10的数字,然后连接两个集合:
@Test
public void whenJoiningTwoCollectionsWithFilter_thenJoined() {
Collection<String> collection1 = Arrays.asList("Dog", "Cat");
Collection<String> collection2 = Arrays.asList("Bird", "Cow", "Moose");
Collection<String> result = Stream.concat(
collection1.stream(), collection2.stream())
.filter(e -> e.length() == 3)
.collect(Collectors.toList());
assertTrue(result.equals(Arrays.asList("Dog", "Cat", "Cow")));
}
5. 将数组连接成字符串
接下来,我们使用收集器将数组连接成字符串:
@Test
public void whenConvertArrayToString_thenConverted() {
String[] animals = new String[] { "Dog", "Cat", "Bird", "Cow" };
String result = Arrays.stream(animals).collect(Collectors.joining(", "));
assertEquals(result, "Dog, Cat, Bird, Cow");
}
6. 将集合连接成字符串
同样地,用集合来做这件事:
@Test
public void whenConvertCollectionToString_thenConverted() {
Collection<String> animals = Arrays.asList("Dog", "Cat", "Bird", "Cow");
String result = animals.stream().collect(Collectors.joining(", "));
assertEquals(result, "Dog, Cat, Bird, Cow");
}
7. 将映射连接成字符串
然后,我们创建一个字符串,基于一个映射。这个过程类似于前面的例子,但我们需要先将每个映射条目连接起来:
@Test
public void whenConvertMapToString_thenConverted() {
Map<Integer, String> animals = new HashMap<>();
animals.put(1, "Dog");
animals.put(2, "Cat");
animals.put(3, "Cow");
String result = animals.entrySet().stream()
.map(entry -> entry.getKey() + " = " + entry.getValue())
.collect(Collectors.joining(", "));
assertEquals(result, "1 = Dog, 2 = Cat, 3 = Cow");
}
8. 连接嵌套的集合成字符串
现在,让我们处理更复杂的情况:将一些嵌套的集合连接成字符串。首先在每个嵌套集合内连接,然后将它们的结果连接起来:
@Test
public void whenConvertNestedCollectionToString_thenConverted() {
Collection<List<String>> nested = new ArrayList<>();
nested.add(Arrays.asList("Dog", "Cat"));
nested.add(Arrays.asList("Cow", "Pig"));
String result = nested.stream().map(
nextList -> nextList.stream()
.collect(Collectors.joining("-")))
.collect(Collectors.joining("; "));
assertEquals(result, "Dog-Cat; Cow-Pig");
}
9. 连接时处理空值
让我们看看如何使用过滤器跳过任何null
值:
@Test
public void whenConvertCollectionToStringAndSkipNull_thenConverted() {
Collection<String> animals = Arrays.asList("Dog", "Cat", null, "Moose");
String result = animals.stream()
.filter(Objects::nonNull)
.collect(Collectors.joining(", "));
assertEquals(result, "Dog, Cat, Moose");
}
10. 将集合分为两部分
接下来,我们将一个数字集合分成两部分:
@Test
public void whenSplitCollectionHalf_thenConverted() {
Collection<String> animals = Arrays.asList(
"Dog", "Cat", "Cow", "Bird", "Moose", "Pig");
Collection<String> result1 = new ArrayList<>();
Collection<String> result2 = new ArrayList<>();
AtomicInteger count = new AtomicInteger();
int midpoint = Math.round(animals.size() / 2);
animals.forEach(next -> {
int index = count.getAndIncrement();
if (index < midpoint) {
result1.add(next);
} else {
result2.add(next);
}
});
assertTrue(result1.equals(Arrays.asList("Dog", "Cat", "Cow")));
assertTrue(result2.equals(Arrays.asList("Bird", "Moose", "Pig")));
}
11. 根据单词长度拆分数组
然后,我们将数组按照单词的长度进行拆分:
@Test
public void whenSplitArrayByWordLength_thenConverted() {
String[] animals = new String[] { "Dog", "Cat", "Bird", "Cow", "Pig", "Moose"};
Map<Integer, List<String>> result = Arrays.stream(animals)
.collect(Collectors.groupingBy(String::length));
assertTrue(result.get(3).equals(Arrays.asList("Dog", "Cat", "Cow", "Pig")));
assertTrue(result.get(4).equals(Arrays.asList("Bird")));
assertTrue(result.get(5).equals(Arrays.asList("Moose")));
}
12. 将字符串拆分为数组
现在,我们来做相反的事情:将字符串拆分为数组:
@Test
public void whenConvertStringToArray_thenConverted() {
String animals = "Dog, Cat, Bird, Cow";
String[] result = animals.split(", ");
assertArrayEquals(result, new String[] { "Dog", "Cat", "Bird", "Cow" });
}
13. 将字符串拆分为集合
这个例子与上一个类似,只是多了一个步骤,将数组转换为集合:
@Test
public void whenConvertStringToCollection_thenConverted() {
String animals = "Dog, Cat, Bird, Cow";
Collection<String> result = Arrays.asList(animals.split(", "));
assertTrue(result.equals(Arrays.asList("Dog", "Cat", "Bird", "Cow")));
}
14. 将字符串拆分为映射
现在,我们将一个字符串拆分为映射。我们需要对字符串进行两次拆分,一次用于每个条目,最后一次用于键和值:
@Test
public void whenConvertStringToMap_thenConverted() {
String animals = "1 = Dog, 2 = Cat, 3 = Bird";
Map<Integer, String> result = Arrays.stream(
animals.split(", ")).map(next -> next.split(" = "))
.collect(Collectors.toMap(entry -> Integer.parseInt(entry[0]), entry -> entry[1]));
assertEquals(result.get(1), "Dog");
assertEquals(result.get(2), "Cat");
assertEquals(result.get(3), "Bird");
}
15. 使用多个分隔符拆分字符串
最后,我们使用正则表达式拆分包含多个分隔符的字符串,并移除空结果:
@Test
public void whenConvertCollectionToStringMultipleSeparators_thenConverted() {
String animals = "Dog. , Cat, Bird. Cow";
Collection<String> result = Arrays.stream(animals.split("[,|.]"))
.map(String::trim)
.filter(next -> !next.isEmpty())
.collect(Collectors.toList());
assertTrue(result.equals(Arrays.asList("Dog", "Cat", "Bird", "Cow")));
}
16. 总结
在这篇教程中,我们利用简单的String.split
函数和强大的Java 8流(Stream),展示了如何连接和拆分数组和集合。你可以在GitHub上找到这篇文章的代码。