使用Java Lambda创建两个(或多个)列表的笛卡尔积集合

4
我可以轻松地在Scala中使用以下代码实现此功能:
def permute(xs: List[Int], ys: List[Int]) = {
  for {x <- xs; y <- ys} yield (x,y)
}

所以如果我给它 {1, 2}, {3, 4},我返回 {1, 3},{1, 4},{2, 3},{2, 4}。我希望能够使用流将其转换为Java 8。但我有点困难,而且我希望能够从不止两个列表中生成许多排列的测试样本。即使使用流,这是否必然会变得很混乱,或者是我没有足够的应用?在意识到我正在寻找笛卡尔积后,找到了一些其他答案。如何在Java 8流中进行笛卡尔积?
2个回答

9
我发现你很难理解你所期望的,看起来你想要进行笛卡尔积计算?比如,给定{1, 2}{3, 4},你期望得到{(1, 3), (1, 4), (2, 3), (2, 4)}吗?(值得一提的是,我认为这与排列的数学定义没有任何关系,排列通常涉及对单个列表内容进行不同的排序方式。)
可以将其写成:
xs.stream()
  .flatMap(x -> ys.stream().map(y -> Pair.of(x, y)))
  .collect(toList());

0
如果你想避免重复,那么你需要使用组合而不是笛卡尔积。消除重复元素的一种方法是在第二个流之后使用过滤器,如下所示。
List<Integer> xs = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7));
List<Integer> ys = new ArrayList<>(Arrays.asList(3, 4, 5, 6, 7));

List<String> combinations =
        xs.stream()
        .flatMap(
                x -> ys.stream()
                .filter( y -> x != y)
                .map(y -> x + ":" + y)
        ).collect(Collectors.toList());
System.out.println(combinations);

这将会得到以下结果:
[1:3, 1:4, 1:5, 1:6, 1:7, 2:3, 2:4, 2:5, 2:6, 2:7, 3:4, 3:5, 3:6, 3:7, 4:3, 4:5, 4:6, 4:7, 5:3, 5:4, 5:6, 5:7, 6:3, 6:4, 6:5, 6:7, 7:3, 7:4, 7:5, 7:6]

我来自未来,这就是我知道的。=)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接