有没有办法只使用`map`而不使用`flatMap`将2D列表转换为1D列表?

frh*_*yme 5 java list java-stream flatmap

我是一名 Java 初学者,我刚刚学习了mapflatMap.

当 2d List 应该转换为 1d List 时,它是如下实现的。

List<List<Integer>> list_2d = List.of(List.of(1, 2), List.of(3, 4));

List<Integer> lst1 = list_2d
    .stream()
    .flatMap(arr -> arr.stream())
    .collect(Collectors.toList());
printAll(lst1); // [1, 2, 3, 4]
Run Code Online (Sandbox Code Playgroud)

但是,我认为它看起来可以不使用flatMap.

有什么方法可以使代码具有相同的逻辑,只是使用map,而不是使用flatMap

只是问,因为如果map可以全部替换flatMap,就没有理由记住flatMap。我总是追求简单和基本的东西。

Ole*_*.V. 9

要回答所问的问题,还有其他方法,但我不会推荐我能想到的任何方法。例如,您可以使用减少:

    List<List<Integer>> list2d = List.of(List.of(1, 2), List.of(3, 4));

    List<Integer> lst1 = list2d
        .stream()
        .reduce((l1, l2) -> {
            ArrayList<Integer> concatenated = new ArrayList<>(l1);
            concatenated.addAll(l2);
            return concatenated;
        })
        .orElse(List.of()); // or else empty list
    
    System.out.println(lst1);
Run Code Online (Sandbox Code Playgroud)

输出与您的相同:

[1, 2, 3, 4]

但是你的代码比我的更容易理解。我建议你坚持下去。

map() 和 flatMap() 不能互换吗?

只是因为,如果 map 可以替代所有 flatMap,就没有理由记住 flatMap。我总是追求简单和基本的东西。

你已经得到了最简单和最基本的东西。此外,为了充分发挥流的潜力,您需要不时使用许多方法调用。在使用流多年之后,我仍然发现自己有时会在 Javadoc 中查找它们。我必须查找reduce()此答案的详细信息。不要指望一切都在你的脑海中。flatMap()不过,我确实知道,因为它通常很实用。

编辑:仅出于学术兴趣:通常您不能flatMap()map(). 或者你会map()从一开始就使用。但反过来说:你总是可以map()flatMap(). 你只是不想。例如,如果我们有:

    List<String> strings = List.of("short", "somewhat longer");
    List<Integer> lengths = strings.stream()
            .map(String::length)
            .collect(Collectors.toList());
    System.out.println(lengths);
Run Code Online (Sandbox Code Playgroud)

[5, 15]

如果出于某种奇怪的原因我们只能记住flatMap(),而不是map(),我们可以这样做:

    List<Integer> lengths = strings.stream()
            .flatMap(s -> Stream.of(s.length()))
            .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

不过,我认为很明显,它给我们带来的只是不必要的复杂化。这是更好的既要记住map()flatMap()至少不够好,可以看看他们的时候,我们需要他们。


Era*_*ran 6

flatMap如果在以下期间执行平面映射,则可以删除collect

List<Integer> lst1 = list_2d
    .stream()
    .collect(Collectors.flatMapping (List::stream, Collectors.toList()));
Run Code Online (Sandbox Code Playgroud)

但是,我没有看到使用Collectors.flatMapping代替flatMap.


Eri*_*ean 5

可能这不是您要查找的内容,但如果目标是将所有子列表添加到一个结果列表中,则使用 for each 也可能是simple 和 basic 的一种选择:

List<List<Integer>> list_2d = List.of(List.of(1, 2), List.of(3, 4));
List<Integer> result = new ArrayList<>();
list_2d.forEach(list -> result.addAll(list));
System.out.println(result);
Run Code Online (Sandbox Code Playgroud)