使用接口流减少操作
Stream reduce operation using interface
我有以下结构
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){
...
}
}
作为复合模式的一部分。
我想使用 streams reduce 操作,但不知何故我无法强制对接口进行类型推断。我正在用这个。
List<Foo> list;
list.stream().reduce( new Foo(), (a,b) -> a.add(b));
我收到一条错误消息,指出 ICommon
无法转换为 Foo
。
我试过强制转换参数但没有成功。
找到问题的解决方案。 reduce 操作具有签名
T reduce(T identity, BinaryOperator<T> accumulator);
我所要做的就是转换为 ICommon
的流
list.stream().map(x-> (ICommon) x).reduce( new Foo(), (a,b) -> a.add(b));
这里的问题是您的 List
参数化为 Foo
,但由于 add
调用,您的缩减操作将参数化为 ICommon
。
虽然所有 Foo
都是 ICommon
,但并非所有 ICommon
都是 Foo
。
最简单的方法是将 List
参数化为 ICommon
,而不更改(可见)代码中的任何其他内容。
类似于:
List<ICommon> list = [some list of Foos];
list.stream().reduce( new Foo(), (a,b) -> a.add(b));
reduce
的三参数版本允许在执行缩减时更改元素类型:
list.stream().reduce(new Foo(), ICommon::add, ICommon::add);
虽然这里使用了对相同方法的引用,但第二个参数是一个带有(ICommon,Foo) -> ICommon
签名的函数(BiFunction
),而第三个参数是一个函数(BinaryOperator
) 带有 (ICommon,ICommon) -> ICommon
签名。
另一种选择是对现有 List
的类型进行类型安全更改:
Collections.<ICommon>unmodifiableList(list).stream().reduce(new Foo(), ICommon::add);
由于不可变列表可以保证实际元素类型的超类型的 return 值,同时防止插入新元素,此包装器允许将元素类型更改为超类型。此外,由于流操作是只读操作,包装器将 stream()
调用重定向到原始列表,只是 return 将其作为超类型的流。所以直接使用 list.stream()
没有性能差异。
我有以下结构
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){
...
}
}
作为复合模式的一部分。
我想使用 streams reduce 操作,但不知何故我无法强制对接口进行类型推断。我正在用这个。
List<Foo> list;
list.stream().reduce( new Foo(), (a,b) -> a.add(b));
我收到一条错误消息,指出 ICommon
无法转换为 Foo
。
我试过强制转换参数但没有成功。
找到问题的解决方案。 reduce 操作具有签名
T reduce(T identity, BinaryOperator<T> accumulator);
我所要做的就是转换为 ICommon
list.stream().map(x-> (ICommon) x).reduce( new Foo(), (a,b) -> a.add(b));
这里的问题是您的 List
参数化为 Foo
,但由于 add
调用,您的缩减操作将参数化为 ICommon
。
虽然所有 Foo
都是 ICommon
,但并非所有 ICommon
都是 Foo
。
最简单的方法是将 List
参数化为 ICommon
,而不更改(可见)代码中的任何其他内容。
类似于:
List<ICommon> list = [some list of Foos];
list.stream().reduce( new Foo(), (a,b) -> a.add(b));
reduce
的三参数版本允许在执行缩减时更改元素类型:
list.stream().reduce(new Foo(), ICommon::add, ICommon::add);
虽然这里使用了对相同方法的引用,但第二个参数是一个带有(ICommon,Foo) -> ICommon
签名的函数(BiFunction
),而第三个参数是一个函数(BinaryOperator
) 带有 (ICommon,ICommon) -> ICommon
签名。
另一种选择是对现有 List
的类型进行类型安全更改:
Collections.<ICommon>unmodifiableList(list).stream().reduce(new Foo(), ICommon::add);
由于不可变列表可以保证实际元素类型的超类型的 return 值,同时防止插入新元素,此包装器允许将元素类型更改为超类型。此外,由于流操作是只读操作,包装器将 stream()
调用重定向到原始列表,只是 return 将其作为超类型的流。所以直接使用 list.stream()
没有性能差异。