在本文中,我们将学习Java中的嵌套集合,以及如何使用不同的方法将它们转换为平面集合。
1.什么是展平?
在编程中,展平列表意味着合并多个嵌套列表以创建一个单一列表。展平的列表包含来自嵌套列表的所有元素。
嵌套List: [[4, 5, 2], [1, 34, 23], [12], [10, 11, 15]];
展平 List: [4, 5, 2, 1, 34, 23, 12, 10, 11, 15];
我们在每个解决方案中使用以下嵌套列表进行演示。
List<List<String>> nestedList = List.of(
List.of("Alexandru", "John"),
List.of("Emma","Andrew", "Luke"),
List.of("Oliver"));
2. 使用自定义逻辑
最基本的解决方案之一是迭代嵌套列表,并将所有元素添加到新声明的平坦列表中。我们可以使用addAll()
函数批量添加所有元素。
List<String> flatList = new ArrayList<>();
nestedList.forEach(flatList::addAll);
如果原始列表还包含单个元素,那么我们需要使用if-else条件来首先检查元素的类型。
List<String> flatList = new ArrayList<>();
for (Object item : nestedList) {
if (item instanceof List<?>) {
flatList.addAll(item)
} else {
flatList.add((String) item);
3. 使用流
Java Streams API为我们提供了一些有趣的方法,用于展平嵌套链表。
3.1. 使用flatMap()
我们可以使用flatMap()
函数与映射函数Collection::stream
。
在执行流终端操作时,flatMap()的每个元素都提供一个单独的流。在最终阶段,flatMap()方法将所有流转换为新流。
List<String> flatList = nestedList.stream()
.flatMap(Collection::stream)
.collect(Collectors.toList());
3.2. 使用reduce()
减少是一种终端方法,用于聚合流。在reduce()
方法中,我们向函数提供两个参数:第一个称为identity,即减少的默认值,第二个称为accumulator,用于组合两个值。
在我们的情况下,为了获得展平的列表,我们需要迭代Stream,并将连续的列表合并成每个后续嵌套列表的一个列表。请注意,由于在运行时创建了额外的ArrayList实例,这种方法不适用于大型嵌套列表的性能。
List<String> flatList = nestedList.stream()
.reduce(new ArrayList<>(), (l1, l2) -> {
l1.addAll(l2);
return l1;
4. 使用Eclipse Collection
展平列表的另一种方法是使用Eclipse Collections的flatCollect()方法。Eclipse Collections是一个具有丰富API的与JDK兼容的List、Map和Set实现的Java集合框架。
将Eclipse Collection的最新版本添加到应用程序中。
<dependency>
<groupId>org.eclipse.collections</groupId>
<artifactId>eclipse-collections</artifactId>
<version>11.1.0</version>
</dependency>
我们将使用ListAdapter
类,它提供了一个围绕JDK Collections List接口实例的MutableList包装器,并将Java List转换为Eclipse Collection MutableList。然后,我们将使用它的flatCollect()
方法来展平列表。
List<String> flatList = ListAdapter.adapt(nestedList).flatCollect(e -> e);
5. 使用Guava
从Maven仓库添加Guava的最新版本。
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>31.1-jre</version>
</dependency>
Iterables.concat()
方法非常适合从嵌套列表创建平坦列表。该方法将多个可迭代对象合并为单个可迭代对象。
Iterable<String> iterable = Iterables.concat(nestedList);
List<String> flatList = Lists.newArrayList(iterable);
6. 结论
展平嵌套列表在开始时可能会看起来很难,但实际上并不难。可以使用纯Java逻辑、流,甚至是外部集合库轻松完成这项任务。
喜欢 (0)赏