Java 如何为通用ArrayList编写reduce函数<;T>;经溪流

Java 如何为通用ArrayList编写reduce函数<;T>;经溪流,java,java-stream,Java,Java Stream,我的任务是实现一个自定义类来模拟集合的属性(不使用集合的任何数据结构)。因此,我选择将T类型的元素作为类的字段存储到ArrayList中 class CustomSet<T> { private final ArrayList<T> elementList; CustomSet() { // when initialising an empty set this.elementList = new ArrayList&l

我的任务是实现一个自定义类来模拟集合的属性(不使用集合的任何数据结构)。因此,我选择将T类型的元素作为类的字段存储到ArrayList中

class CustomSet<T> {
    
    private final ArrayList<T> elementList;
    
    CustomSet() { // when initialising an empty set
        this.elementList = new ArrayList<>();
    }

    private CustomSet(ArrayList<T> otherElementList) { // When passing in a list to construct the set
        this.elementList = otherElementList;
    }

    static <T> CustomSet<T> of(T...elem) {
        ArrayList<T> set = new ArrayList<>();
        for (T e: elem) {
            set.add(e);
        }
        return new CustomSet<T>(set);
    }

    // typical add, clear, remove functions for the set which can be done with methods in ArrayList

}
类自定义集{
私有最终ArrayList元素列表;
CustomSet(){//初始化空集时
this.elementList=新的ArrayList();
}
私有CustomSet(ArrayList otherElementList){//传入列表以构造集合时
this.elementList=otherElementList;
}
静态自定义集(T…元素){
ArrayList集合=新的ArrayList();
for(te:elem){
增加(e);
}
返回新的CustomSet(set);
}
//可以使用ArrayList中的方法完成集合的典型添加、清除和删除函数
}
我的任务之一是实现一个reduce函数,它接受一个seed和一个二进制操作符来返回缩减值(不使用显式循环,即使用流),这样就可以观察到以下情况

CustomSet<Integer> thisSet = CustomSet.of(1,2,3,4,5,6);
thisSet.reduce(0, (subtotal, element) -> subtotal + element) // outputs 21

CustomSet<String> otherSet = CustomSet.of("a", "b", "c", "d", "e");
otherSet.reduce("", (partialString, element) -> partialString + element); // outputs "abcde"
CustomSet thisSet=CustomSet.of(1,2,3,4,5,6);
thisSet.reduce(0,(小计,元素)->小计+元素)//输出21
CustomSet-otherSet=自定义集合,共有(“a”、“b”、“c”、“d”、“e”);
otherSet.reduce(“,(partialString,element)->partialString+element);//产出“abcde”
我试着这样写代码

<U> U reduce(U identity, BiFunction<U, ? super T, U> acc) {
    return elementsList.stream().reduce(identity, acc, (x,y) -> x + y); 
// error which says Operator "+" cannot be applied to 'U', 'U'
}
U减少(U标识,双功能acc){
return elementsList.stream().reduce(identity,acc,(x,y)->x+y);
//表示运算符“+”不能应用于“U”、“U”的错误
}
但是,它运行到上面的以下错误。我如何解决这个问题

编辑

这与将下面的代码转换为使用流的代码相同

<U> U reduce(U identity, BiFunction<U, ? super T, U> acc) {
    for (T ele: elementsList) {
        identity = acc.apply(identity, ele);
    }
    return identity;
}
U减少(U标识,双功能acc){
for(T元素:元素列表){
标识=acc.apply(标识,ele);
}
返回身份;
}

我建议减少方法签名

U-reduce(U标识、双功能累加器、二进制运算符组合器){
return elementList.stream().reduce(标识、累加器、合并器);
}
像这样使用它

CustomSet thisSet=CustomSet.of(1,2,3,4,5,6);
thisSet.reduce(0,(小计,元素)->小计+元素,整数::和);//产出21
CustomSet-otherSet=自定义集合,共有(“a”、“b”、“c”、“d”、“e”);
otherSet.reduce(“,(partialString,element)->partialString+element,(a,b)->a+b);//产出“abcde”

必须启用还原功能。
双功能acc
通常不能关联。这就是为什么Java的流API需要一个兼容的
BinaryOperator
作为它的方法。加号运算符不是兼容的第三个参数,不可能从第二个参数派生出有效的第三个参数,否则,就不需要坚持第三个参数

我们可以说,你的任务不是一项真正的任务,而是一项经常与削减相混淆的行动

流API中没有对左折叠操作的直接支持,虽然可以在没有显式循环的情况下构建它,但它不是一个干净的操作,而是一个伪装的循环

U左折叠(U标识,双功能acc){
列表值=数组.asList(标识);
elementsList.forEach(t->value.replaceAll(u->acc.apply(u,t));
返回值.get(0);
}

为什么不简单地实现接口
T reduce(T identity,BinaryOperator累加器)
,它将是
返回elementList.stream().reduce(标识,累加器)这应该满足您列出的两种情况。不幸的是,我无法更改方法签名。所示示例是公共测试用例的输入