列表的列表的列表(用 N 深度展平 ArrayList)

发布于 2025-01-16 21:08:48 字数 839 浏览 5 评论 0 原文

我正在尝试用 N 深度展平 ArrayList。为此,我尝试使用 Stream API 的flapMap 方法。我能够得到它。但我必须根据列表列表的数量重复使用 flatMap() 方法。如果我再使用一种 flatMap() 方法,它会显示编译时错误。有什么办法可以动态地完成它。

这是我使用的代码:

List<Integer> list1 = Arrays.asList(4,5,6);
List<Integer> list2 = Arrays.asList(7,8,9);

List<List<Integer>> listOfLists = Arrays.asList(list1, list2);

List<List<List<Integer>>> listA = Arrays.asList(listOfLists);
List<List<List<List<Integer>>>> listB = Arrays.asList(listA);

List<Integer> listFinal = listB.stream()
    .flatMap(x -> x.stream())
    .flatMap(x -> x.stream())
    .flatMap(x -> x.stream())
    .collect(Collectors.toList());
//In the above line, If I use listA instead of listB, it is showing error.

listFinal.forEach(x-> System.out.println(x));

I am trying to Flatten a ArrayList with N-Depth. For this I tried using flapMap method of Stream API. I am able to get it. But I have to use flatMap() method repeatedly as per the number of list of lists. If I am using one more flatMap() method, it shows compile time error. Is there any way to dynamically get it done.

This is the code that I used:

List<Integer> list1 = Arrays.asList(4,5,6);
List<Integer> list2 = Arrays.asList(7,8,9);

List<List<Integer>> listOfLists = Arrays.asList(list1, list2);

List<List<List<Integer>>> listA = Arrays.asList(listOfLists);
List<List<List<List<Integer>>>> listB = Arrays.asList(listA);

List<Integer> listFinal = listB.stream()
    .flatMap(x -> x.stream())
    .flatMap(x -> x.stream())
    .flatMap(x -> x.stream())
    .collect(Collectors.toList());
//In the above line, If I use listA instead of listB, it is showing error.

listFinal.forEach(x-> System.out.println(x));

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

煮酒 2025-01-23 21:08:48

这似乎对我有用,使用递归。当给定一个列表时,

  • 检查它是否是一个整数列表,在这种情况下返回它。
  • 否则它是一个列表的列表。 FlatMap 它(以删除 1 层嵌套),并展平生成的列表。
private static List<Integer> flatten(List<?> list) {
    if (list.get(0) instanceof Integer) {
        return (List<Integer>) list;
    }

    List<List<?>> listOfLists = (List<List<?>>) list;
    return flatten(listOfLists.stream()
            .flatMap(Collection::stream)
            .collect(Collectors.toList()));
}

然后

public static void main(String[] args) {
    List<List<List<List<List<Integer>>>>> listC = Arrays.asList(
            Arrays.asList(
                    Arrays.asList(
                            Arrays.asList(
                                    Arrays.asList(0, 1),
                                    Arrays.asList(2, 3, 4)
                            ),
                            Arrays.asList(
                                    Arrays.asList(5),
                                    Arrays.asList(6, 7),
                                    Arrays.asList(8, 9)
                            )
                    ),
                    Arrays.asList(
                            Arrays.asList(
                                    Arrays.asList(10, 11),
                                    Arrays.asList(12, 13, 14)
                            ),
                            Arrays.asList(
                                    Arrays.asList(15),
                                    Arrays.asList(16, 17),
                                    Arrays.asList(18, 19)
                            )
                    )
            ),
            Arrays.asList(
                    Arrays.asList(
                            Arrays.asList(
                                    Arrays.asList(20, 21),
                                    Arrays.asList(22, 23, 24)
                            ),
                            Arrays.asList(
                                    Arrays.asList(25),
                                    Arrays.asList(26, 27),
                                    Arrays.asList(28, 29)
                            )
                    ),
                    Arrays.asList(
                            Arrays.asList(
                                    Arrays.asList(30, 31),
                                    Arrays.asList(32, 33, 34)
                            ),
                            Arrays.asList(
                                    Arrays.asList(35),
                                    Arrays.asList(36, 37),
                                    Arrays.asList(38, 39)
                            )
                    )
            )
    );

    List<Integer> result = flatten(listC);

    System.out.println(listC);
    System.out.println(result);

}

打印

[[[[[0, 1], [2, 3, 4]], [[5], [6, 7], [8, 9]]], [[[10, 11], [12, 13, 14]], [[15], [16, 17], [18, 19]]]], [[[[20, 21], [22, 23, 24]], [[25], [26, 27], [28, 29]]], [[[30, 31], [32, 33, 34]], [[35], [36, 37], [38, 39]]]]]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39]

There is a bit of Uncheckedcasting正在进行,但不知道如何做没有

This seems to work for me, using recursion. When given a list

  • check if it is a list of Integer, in which case return it.
  • otherwise it is a list of lists. FlatMap it (to remove 1 level of nesting), and flatten the resulting list.
private static List<Integer> flatten(List<?> list) {
    if (list.get(0) instanceof Integer) {
        return (List<Integer>) list;
    }

    List<List<?>> listOfLists = (List<List<?>>) list;
    return flatten(listOfLists.stream()
            .flatMap(Collection::stream)
            .collect(Collectors.toList()));
}

then

public static void main(String[] args) {
    List<List<List<List<List<Integer>>>>> listC = Arrays.asList(
            Arrays.asList(
                    Arrays.asList(
                            Arrays.asList(
                                    Arrays.asList(0, 1),
                                    Arrays.asList(2, 3, 4)
                            ),
                            Arrays.asList(
                                    Arrays.asList(5),
                                    Arrays.asList(6, 7),
                                    Arrays.asList(8, 9)
                            )
                    ),
                    Arrays.asList(
                            Arrays.asList(
                                    Arrays.asList(10, 11),
                                    Arrays.asList(12, 13, 14)
                            ),
                            Arrays.asList(
                                    Arrays.asList(15),
                                    Arrays.asList(16, 17),
                                    Arrays.asList(18, 19)
                            )
                    )
            ),
            Arrays.asList(
                    Arrays.asList(
                            Arrays.asList(
                                    Arrays.asList(20, 21),
                                    Arrays.asList(22, 23, 24)
                            ),
                            Arrays.asList(
                                    Arrays.asList(25),
                                    Arrays.asList(26, 27),
                                    Arrays.asList(28, 29)
                            )
                    ),
                    Arrays.asList(
                            Arrays.asList(
                                    Arrays.asList(30, 31),
                                    Arrays.asList(32, 33, 34)
                            ),
                            Arrays.asList(
                                    Arrays.asList(35),
                                    Arrays.asList(36, 37),
                                    Arrays.asList(38, 39)
                            )
                    )
            )
    );

    List<Integer> result = flatten(listC);

    System.out.println(listC);
    System.out.println(result);

}

prints

[[[[[0, 1], [2, 3, 4]], [[5], [6, 7], [8, 9]]], [[[10, 11], [12, 13, 14]], [[15], [16, 17], [18, 19]]]], [[[[20, 21], [22, 23, 24]], [[25], [26, 27], [28, 29]]], [[[30, 31], [32, 33, 34]], [[35], [36, 37], [38, 39]]]]]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39]

There is a bit of Unchecked casting going on, but not sure how to do without

护你周全 2025-01-23 21:08:48

对于List>>> listB, .stream().flatMap(.stream()).flatMap(.stream()).flatMap(.stream()).collect()

但是对于 列表<列表<列表<整数>>> listA.stream().flatMap(.stream()).flatMap(.stream()).collect()

请参阅 flatMap() 计数仅比通用深度少 1。

For List<List<List<List<Integer>>>> listB, .stream().flatMap(.stream()).flatMap(.stream()).flatMap(.stream()).collect()

But for List<List<List<Integer>>> listA, .stream().flatMap(.stream()).flatMap(.stream()).collect().

See flatMap() count is just one less than the Generic depth.

琴流音 2025-01-23 21:08:48

我希望您知道深度嵌套的集合并不是表示数据的最佳方式,必须避免(它几乎肯定是错误设计的指标)。因此,我将把这个问题视为一个神秘的谜题,而不是一个实际任务。

您可以在不使用递归的情况下实现这一点。但请注意,这种方法和递归一样都是恶性的,因为递归方法也需要放弃泛型提供的类型安全我警告过你不应该'首先不要这样做)。

为此,您需要在循环中执行instanceof检查。并使用嵌套列表的元素填充行类型的结果列表。

注意

  • 与常用的泛型集合相反,例如List,其特征为协变即您可以分配相同类型的集合给它)您可以将任何东西分配给< em>行类型 和修改它。这是一个不安全的组合,因此强烈建议不要使用行类型集合。

如果第一个元素不是列表,则循环退出。

public static void main(String[] args) {
    List<List<List<List<Integer>>>> source =
            List.of(List.of(List.of(List.of(4,5,6), List.of(7,8,9))));

    List<Integer> result = source.stream()
            .flatMap(list -> deepFlatten(list).stream())
            .collect(Collectors.toList());
    
    System.out.println(source);
    System.out.println(result);
}

public static List<Integer> deepFlatten(List<?> nestedList) {
    if (nestedList.isEmpty()) {
        return (List<Integer>) nestedList;
    }

    List result = new ArrayList<>();
    List current = nestedList;
    while (current.get(0) instanceof List<?>) {
        for (Object next: current) {
            result.addAll((List) next);
        }
        current = result;
        result = new ArrayList<>();
    }
    return (List<Integer>) current;
}

输出

[[[[4, 5, 6], [7, 8, 9]]]]
[4, 5, 6, 7, 8, 9]

I hope you know that deeply nested collections isn't the best way to represent the data and must be avoided (it's an almost certain indicator of faulty design). So I'll treat this question as a cryptic puzzle rather than a practical task.

You can achieve that without using recursion. But caution this approach is vicious as well recursion because as well recursive approach it requires to relinquish the type safety provided by generics (I've warned that you shouldn't do that in the first place).

To do that, you need to perform intanceof checks in a loop. And populate the resulting list of row type with elements of a nested list.

Note :

  • contrary to commonly used generic collections like List<Integer> which characterized as covariant (i.e. you can assign only collection of the same type to it) you're allowed and to assign anything to the list of row type and to modify it as well. Which is an unsafe combination, and hence usage of row type collections is highly discouraged.

The loop exits if the first element isn't a list.

public static void main(String[] args) {
    List<List<List<List<Integer>>>> source =
            List.of(List.of(List.of(List.of(4,5,6), List.of(7,8,9))));

    List<Integer> result = source.stream()
            .flatMap(list -> deepFlatten(list).stream())
            .collect(Collectors.toList());
    
    System.out.println(source);
    System.out.println(result);
}

public static List<Integer> deepFlatten(List<?> nestedList) {
    if (nestedList.isEmpty()) {
        return (List<Integer>) nestedList;
    }

    List result = new ArrayList<>();
    List current = nestedList;
    while (current.get(0) instanceof List<?>) {
        for (Object next: current) {
            result.addAll((List) next);
        }
        current = result;
        result = new ArrayList<>();
    }
    return (List<Integer>) current;
}

Output

[[[[4, 5, 6], [7, 8, 9]]]]
[4, 5, 6, 7, 8, 9]
天邊彩虹 2025-01-23 21:08:48

下面的代码片段对我有用。感谢大家的回复。

列表 list1 = Arrays.asList(4,5,6);
列表 list2 = Arrays.asList(7,8,9);

    List<List<Integer>> listOfLists = Arrays.asList(list1, list2);

    List< List< List<Integer> > > list = Arrays.asList(listOfLists);
    List< List< List<List<Integer>> > > listB = Arrays.asList(list);
    
    
    //List<Integer> listF = listB.stream().flatMap(x -> x.stream()).flatMap(x -> x.stream()).flatMap(x -> x.stream()).collect(Collectors.toList());
    
    List<Integer> flattenList = (List<Integer>) getList(listB);
    flattenList.forEach(x-> System.out.println(x));
    
    
}
public static List<?> getList(List<? > s) {
    
    if( s.isEmpty() || !( s.get(0) instanceof List) ) {
        return s;
    }
    
    return getList( (List<?>) s.stream().flatMap(x-> ((List)x).stream()).collect(Collectors.toList()));
}

The below snippet worked for me. Thanks for the response all.

List list1 = Arrays.asList(4,5,6);
List list2 = Arrays.asList(7,8,9);

    List<List<Integer>> listOfLists = Arrays.asList(list1, list2);

    List< List< List<Integer> > > list = Arrays.asList(listOfLists);
    List< List< List<List<Integer>> > > listB = Arrays.asList(list);
    
    
    //List<Integer> listF = listB.stream().flatMap(x -> x.stream()).flatMap(x -> x.stream()).flatMap(x -> x.stream()).collect(Collectors.toList());
    
    List<Integer> flattenList = (List<Integer>) getList(listB);
    flattenList.forEach(x-> System.out.println(x));
    
    
}
public static List<?> getList(List<? > s) {
    
    if( s.isEmpty() || !( s.get(0) instanceof List) ) {
        return s;
    }
    
    return getList( (List<?>) s.stream().flatMap(x-> ((List)x).stream()).collect(Collectors.toList()));
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文