我有以下结构

public interface ICommon{
   ICommon add(ICommon other);
}

public class Foo implements ICommon{
    ...

    ICommon add(ICommon other){
        return new Bar().add(other);
    }

}

public class Bar implements ICommon{
    ...

    ICommon add(ICommon other){
        ...
    }

}


作为复合模式的一部分。

我想使用流减少操作,但是以某种方式我无法将类型推断强制给接口。我正在用这个。

List<Foo> list;
list.stream().reduce( new Foo(), (a,b) -> a.add(b));


我收到一个错误,指出ICommon无法转换为Foo

我试图强制对参数进行强制转换,但没有成功。

最佳答案

reduce的三个参数版本允许在执行归约时更改元素类型:

list.stream().reduce(new Foo(), ICommon::add, ICommon::add);


虽然此处使用对同一方法的引用,但第二个参数是带有BiFunction签名的函数((ICommon,Foo) -> ICommon),而第三个参数是带有BinaryOperator签名的函数((ICommon,ICommon) -> ICommon)。

另一种选择是对现有List类型进行类型安全更改:

Collections.<ICommon>unmodifiableList(list).stream().reduce(new Foo(), ICommon::add);


由于不可变列表可以保证返回实际元素类型的超级类型的值,同时防止插入新元素,因此该包装器允许将元素类型更改为超级类型。此外,由于流操作是只读操作,因此包装程序将stream()调用重定向到原始列表,只是将其作为超类型的流返回。因此,直接使用list.stream()没有性能差异。

关于java - 使用接口(interface)进行流减少操作,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48116656/

10-13 04:33