如何将嵌套Java集合中的所有项目展平为单个列表? [英] How to flatten all items from a nested Java Collection into a single List?

查看:1348
本文介绍了如何将嵌套Java集合中的所有项目展平为单个列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个复杂的嵌套对象集合,例如:

Given a complex nested collection of objects such as:

Set<List<Map<String, List<Object>>>> complexNestedCollection;

是否存在通用方法来平衡这个并获得单个 List 包含在所有对象中?

Does a generic method exist to flatten this out and get a single List of all Objects contained within?

一些细节:


  1. 该列表不应包含集合对象本身或映射键 - 仅包含最低级别的值。

  2. 它应尽可能遵循相同的顺序 - 因此在示例中,列表中的项目将按顺序排列,而地图/集合的排序将取决于实现。

  3. 它可以选择性地排除重复项

  4. UPDATE:理想情况下,它应检测/处理任何级别的循环引用,例如a 列表< List< Object>> 其中外部List将自身包含为成员。 (感谢AdrianJałoszewski在下面的评论中提到这一点)。

  1. The list shouldn't include collection objects themselves or map keys - only the values at the lowest level.
  2. It should follow the same ordering where possible - so in the example, items in the list would be in order, whereas ordering of maps/sets would depend on the implementation.
  3. It could optionally exclude duplicates
  4. UPDATE: It should ideally detect/handle circular references at any level, e.g. a List<List<Object>> where the outer List contains itself as a member. (Credit to Adrian Jałoszewski for mentioning this in the comments below).

注意:实际用例是获取所有来自列表< List< String>> 的字符串,可以通过两个循环轻松完成,但它让我对一般情况感到疑惑。

Note: The actual use case is to get all Strings from a List<List<String>>, which can be done easily enough with two loops but it made me wonder about the general case.

推荐答案

假设您使用 Java 8 ,您可以使用 Stream API 感谢方法 flatMap(函数<?super T,?extends Stream<?extends R>> mapper) 作为下一个:

Assuming that you use Java 8, you could do that with the Stream API thanks to the method flatMap(Function<? super T,? extends Stream<? extends R>> mapper) as next:

// 1. Convert the Set as a Stream of List<Map<String, List<Object>>>
// 2. Extract the elements of the lists to get a Stream of Map<String, List<Object>>
// 3. Extract values of the maps to get a Stream of List<Object>
// 4. Extract the elements of the lists to get a Stream of Object
// 5. Get rid of duplicates
// 6. Collect the result as a List of Object
List<Object> result = complexNestedCollection.stream()
    .flatMap(List::stream)
    .flatMap(m -> m.values().stream())
    .flatMap(List::stream)
    .distinct()
    .collect(Collectors.toList());




< R>流< R> flatMap(函数<?super T ,? extends Stream<?extends
R>> mapper)

返回一个包含的流将每个元素
替换为
生成的映射流的内容,将提供的映射函数应用于每个元素。每个映射的
流在其内容放入此流后关闭。
(如果映射的流为空,则使用空流。)

Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element. Each mapped stream is closed after its contents have been placed into this stream. (If a mapped stream is null an empty stream is used, instead.)






对于以前的版本 Java ,您仍然可以使用的/releases/snapshot/api/docs/com/google/common/collect/FluentIterable.html\"rel =nofollow noreferrer> FluentIterable Google Guava 替换 Stream 并使用 transformAndConcat(函数<?super E,?extends Iterable< ?扩展T>>>>>>功能) 而不是 flatMap 来展平您的收藏。


For previous versions of Java, you can still use FluentIterable from Google Guava to replace the Stream and use transformAndConcat(Function<? super E,? extends Iterable<? extends T>> function) instead of flatMap to flatten your collection.

之前的代码段将被重写为下一个:

List<Object> result =
    new ArrayList<>(
        new LinkedHashSet<>(
            FluentIterable.from(complexNestedCollection)
                .transformAndConcat(
                    new Function<List<Map<String, List<Object>>>, Iterable<Map<String, List<Object>>>> () {
                        public Iterable<Map<String, List<Object>>> apply(final List<Map<String, List<Object>>> input) {
                            return input;
                        }
                    }
                ).transformAndConcat(
                    new Function<Map<String, List<Object>>, Iterable<List<Object>>> () {
                        public Iterable<List<Object>> apply(final Map<String, List<Object>> input) {
                            return input.values();
                        }
                    }
                ).transformAndConcat(
                    new Function<List<Object>, Iterable<Object>> () {
                        public Iterable<Object> apply(final List<Object> input) {
                            return input;
                        }
                    }
                ).toList()
        )
    );

这篇关于如何将嵌套Java集合中的所有项目展平为单个列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆