当前位置: 首页 > 知识库问答 >
问题:

用Java8实现集合的笛卡尔积

王曜文
2023-03-14

现在我只能实现两个集合的笛卡尔积,下面是代码:

public static <T1, T2, R extends Collection<Pair<T1, T2>>>
R getCartesianProduct(
        Collection<T1> c1, Collection<T2> c2,
        Collector<Pair<T1, T2>, ?, R> collector) {
    return c1.stream()
            .flatMap(e1 -> c2.stream().map(e2 -> new Pair<>(e1, e2)))
            .collect(collector);
}

这段代码在IntelliJ中运行良好,但在Eclipse(两者的编译器遵从级别均为1.8)中就不行了:

The method collect(Collector<? super Object,A,R>) 
in the type Stream<Object> is not applicable for 
the arguments (Collector<Pair<T1,T2>,capture#5-of ?,R>)

下面是pair.java:

public class Pair<T1, T2> implements Serializable {
    protected T1 first;
    protected T2 second;
    private static final long serialVersionUID = 1360822168806852921L;

    public Pair(T1 first, T2 second) {
        this.first = first;
        this.second = second;
    }

    public Pair(Pair<T1, T2> pair) {
        this(pair.getFirst(), pair.getSecond());
    }

    public T1 getFirst() {
        return this.first;
    }

    public T2 getSecond() {
        return this.second;
    }

    public void setFirst(T1 o) {
        this.first = o;
    }

    public void setSecond(T2 o) {
        this.second = o;
    }

    public String toString() {
        return "(" + this.first + ", " + this.second + ")";
    }

    @Override
    public boolean equals(Object o) {
        if(!(o instanceof Pair))
            return false;
        Pair p = (Pair) o;
        if(!this.first.equals(p.first))
            return false;
        if(!this.second.equals(p.second))
            return false;
        return true;

    }

    @Override
    public int hashCode() {
        int hash = 1;
        hash = hash * 31 + this.first.hashCode();
        hash = hash * 31 + this.second.hashCode();
        return hash;
    }

}

如何修复这个错误?

有没有一个优雅的方法来实现几个收藏的笛卡尔产品?(假设我们有类tuple)

共有1个答案

季炯
2023-03-14

Eclipse在类型推断方面存在问题。如果添加一个类型提示. >flatmap ,那么它可以很好地编译。

如果我可以建议一种不同的方法,请考虑让您的cartesianProduct不处理整个流和集合,而只是FlatMap的助手:

static <T1, T2, R> Function<T1, Stream<R>> crossWith(
         Supplier<? extends Stream<T2>> otherSup, 
         BiFunction<? super T1, ? super T2, ? extends R> combiner
) {
    return t1 -> otherSup.get().map(t2 -> combiner.apply(t1, t2));
}

现在,如果希望结果包含pair,则只需要创建一个pair,并且可以通过多次应用flatmap来执行高阶笛卡尔积:

List<String> letters = Arrays.asList("A", "B", "C");
List<Integer> numbers = Arrays.asList(1, 2, 3);

List<Pair<String, Integer>> board = letters.stream()
                .flatMap(crossWith(numbers::stream, Pair::new))
                .collect(toList());


List<String> ops = Arrays.asList("+", "-", "*", "/");

List<String> combinations = letters.stream()
                .flatMap(crossWith(ops::stream, String::concat))
                .flatMap(crossWith(letters::stream, String::concat))
                .collect(toList());   // triple cartesian product
 类似资料:
  • 现在我只能实现两个集合的笛卡尔积,下面是代码: 这段代码在IntelliJ中运行良好,但在Eclipse中不起作用。编译器符合性级别均为1.8: 这里是Pair.java: 如何修复此错误? 有没有一种优雅的方法来实现几个集合的笛卡尔产品?假设我们有类。

  • 我有以下收藏类型: 我希望根据集合中每个键的单个值为每个创建唯一的组合。

  • 本文向大家介绍map reduce实现笛卡尔乘积?相关面试题,主要包含被问及map reduce实现笛卡尔乘积?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 在Map阶段,将来自矩阵A的元素标识成l条<key,value>的形式,key=(i,k),k=1,2,…,l。value=(j,)。将来自矩阵B的元素标识成l条<key,value>的形式,key=(i,k),k=1,2,…,m。

  • 问题内容: 你是否知道一些精巧的Java库,可让你制作两个(或更多)集合的笛卡尔积? 例如:我有三套。一个对象是Person类的对象,第二个对象是Gift的对象,第三个对象是GiftExtension的对象。 我想生成一个包含所有可能的三元组的集合。 集的数量可能会有所不同,因此我无法在嵌套的foreach循环中执行此操作。在某些情况下,我的应用程序需要制作Person-Gift对的乘积,有时是的

  • 本文向大家介绍javascript笛卡尔积算法实现方法,包括了javascript笛卡尔积算法实现方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了javascript笛卡尔积算法实现方法。分享给大家供大家参考。具体分析如下: 这里可根据给的对象或者数组生成笛卡尔积 希望本文所述对大家的javascript程序设计有所帮助。

  • 本文向大家介绍PHP笛卡尔积实现算法示例,包括了PHP笛卡尔积实现算法示例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了PHP笛卡尔积实现算法。分享给大家供大家参考,具体如下: 最终输出格式 Array (     [0] => 1,3,76     [1] => 1,3,6     [2] => 1,3,1     [3] => 1,3,0     [4] => 1,5,76