如何使用streams

问题描述 投票:0回答:6

[3, 4]

,结果应为:
[(1, 3), (1, 4), (2, 3), (2, 4), (3, 3), (3, 4)]

我知道我可以使用loop
来做到这一点,但是还有其他简洁的方法可以使用
java8streams

? 我尝试了以下内容,但是我缺少一些东西,因为我得到了List<Stream<int[]>>而不是List<int[]>

public static void main(String[] args) { List<Integer> list1 = Arrays.asList(1, 2, 3); List<Integer> list2 = Arrays.asList(3, 4); List<int[]> pairs = list1.stream() .map(i -> list2.stream() .map(j -> new int[]{i, j})) .collect(Collectors.toList()); pairs.forEach(i -> { System.out.println("{" + i[0] + "," + i[1] + "}"); }); }

    
使用

flatmap()
方法而不是
map()
java list java-8 java-stream cartesian-product
6个回答
17
投票
flatmap()示例

您只需要用map()替换第一个。

flatMap()

15
投票

here是一种使用两个
List<int[]> pairs = list1.stream() .flatMap(i -> list2.stream() .map(j -> new int[]{i, j})) .collect(Collectors.toList()); 阵列作为源而不是
IntStream
的解决方案。 我想看看是否可以解决这个问题,而无需将每个问题拳击为
int

List<Integer>
不幸的是,当它返回

14
投票
时,我无法在

Integer

上使用
int[] one = new int[]{1, 2, 3}; int[] two = new int[]{3, 4}; List<IntIntPair> list = new ArrayList<>(); IntStream.of(one).forEach(i -> IntStream.of(two).mapToObj(j -> PrimitiveTuples.pair(i, j)).forEach(list::add)); System.out.println(list); // [1:3, 1:4, 2:3, 2:4, 3:3, 3:4]
。  目前没有
flatMap
IntStream
,这里需要的是。  所以我用了
IntStream
我从

eclipseCollections
使用的类和

flatMapToObj

类,因为它们使仅作为字符串输出列表变得更加简单。  您可以像解决方案中一样使用
IntStream
。 代码看起来如下。
forEach
在8.1释放Eclipse集合(将在3月中旬发布),现在在库中所有原始容器上都有一个方法,可用于解决此问题。  从本质上讲,这实现了
IntIntPair
方法应该做的事情。 
PrimitiveTuples

update:



在蜘蛛鲍里斯(Boris)的评论中指出,
int[]
解决方案不会是线程安全的,如果
List<int[]> list = new ArrayList<>(); IntStream.of(one).forEach(i -> IntStream.of(two).mapToObj(j -> new int[]{i, j}).forEach(list::add)); flatCollect
flatMapToObj

,则会破裂。 以下解决方案应在串行或平行的情况下起作用。 我很高兴指出了这一点,因为我没想到要在
IntStream
上做一个

IntList a = IntLists.mutable.with(1, 2, 3); IntList b = IntLists.mutable.with(3, 4); List<IntIntPair> result = a.flatCollect( i -> b.collect(j -> PrimitiveTuples.pair(i, j)), Lists.mutable.empty()); System.out.println(result); // [1:3, 1:4, 2:3, 2:4, 3:3, 3:4]

,然后是
forEach
IntStream
注:我是collections的委员
    

在此特定情况下,您甚至可以绕过数组创建,并使您的代码更简单:

parallel

mapToObj

您可以使用
IntStream
flatMap
方法生成可能组合的2D列表:
int[] one = new int[]{1, 2, 3};
int[] two = new int[]{3, 4};
List<int[]> list = IntStream.of(one).parallel()
        .mapToObj(i -> IntStream.of(two).mapToObj(j -> new int[]{i, j}))
        .flatMap(e -> e)
        .collect(Collectors.toList());
list.stream().map(e -> "{" + e[0] + "," + e[1] + "}").forEach(System.out::println);

还请参见:
从多个列表中加生所有组合


0
投票
当然,您可以每次创建一个

flatMap

,但就性能而言,它非常差。
Instead,我建议您选择
Java-16

list1.stream()
     .flatMap(i -> list2.stream().map(j -> "{" + i+ "," + j + "}"))
     .forEach(System.out::println);

0
投票
和运营商以更高的方式选择
map

0
投票
reduce

创造的开销

List<Integer> list1 = Arrays.asList(1, 2, 3);
List<Integer> list2 = Arrays.asList(3, 4);

List<List<Integer>> combinations = Stream.of(list1, list2)
        // represent each list element as a singleton list
        .map(list -> list.stream().map(Collections::singletonList)
                // Stream<List<List<Integer>>>
                .collect(Collectors.toList()))
        // intermediate output
        //[[1], [2], [3]]
        //[[3], [4]]
        .peek(System.out::println)
        // summation of pairs of inner lists
        .reduce((listA, listB) -> listA.stream()
                // combinations of inner lists
                .flatMap(inner1 -> listB.stream()
                        // merge two inner lists into one
                        .map(inner2 -> Stream.of(inner1, inner2)
                                .flatMap(List::stream)
                                .collect(Collectors.toList())))
                // list of combinations
                .collect(Collectors.toList()))
        // otherwise an empty list
        .orElse(Collections.emptyList());

// output
System.out.println(combinations);
// [[1, 3], [1, 4], [2, 3], [2, 4], [3, 3], [3, 4]]
	

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.