简体   繁体   English

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

[英]Create collection of cartesian product of two (and more) lists with Java Lambda

I'm able to easily achieve this in Scala with something like:我可以在 Scala 中通过以下方式轻松实现这一点:

def permute(xs: List[Int], ys: List[Int]) = {
  for {x <- xs; y <- ys} yield (x,y)
}

So if I give it {1, 2}, {3, 4} I return {1, 3}, {1, 4}, {2, 3}, {2, 4}所以如果我给它 {1, 2}, {3, 4} 我返回 {1, 3}, {1, 4}, {2, 3}, {2, 4}

I was hoping to be able to translate this to java 8 using streams.我希望能够使用流将其转换为 Java 8。

I'm having a bit of difficulty and I'd like to be able to extend this out farther as I'd like to be able to generate many permuted test samples from more than two lists.我遇到了一些困难,我希望能够将其扩展得更远,因为我希望能够从两个以上的列表中生成许多排列的测试样本。

Will it inevitably be a nested mess even using streams or am I not applying myself enough?即使使用流,它是否不可避免地会出现嵌套混乱,还是我没有充分发挥自己的作用?

Some additional answers were found after realizing that I was looking for a cartesian product:在意识到我正在寻找笛卡尔积后,找到了一些额外的答案:

How can I make Cartesian product with Java 8 streams? 如何使用 Java 8 流制作笛卡尔积?

I'm having difficulty figuring out what you're hoping for, it looks like you're trying to get a Cartesian product?我很难弄清楚你想要什么,看起来你正在尝试获得笛卡尔积? Like, given {1, 2} and {3, 4} , you're expecting {(1, 3), (1, 4), (2, 3), (2, 4)} ?比如,给定{1, 2}{3, 4} ,您期望{(1, 3), (1, 4), (2, 3), (2, 4)} (For what it's worth, I don't think that has any relationship to the mathematical definition of permutations, which generally involve different ways of ordering the contents of a single list.) (就其价值而言,我认为这与排列的数学定义没有任何关系,排列通常涉及对单个列表的内容进行排序的不同方式。)

That could be written可以这么写

xs.stream()
  .flatMap(x -> ys.stream().map(y -> Pair.of(x, y)))
  .collect(toList());

If you want to avoid repetition, then you are after combinations and not Cartesian product.如果你想避免重复,那么你是在组合而不是笛卡尔积之后。 A way to remove repeated elements is to use a filter after your second stream as follows.删除重复元素的一种方法是在第二个流之后使用过滤器,如下所示。

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);

This will get you the following:这将为您提供以下内容:

[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]

I'm coming from the future.我来自未来。 That's how I know this.我就是这样知道的。 =) =)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM