我正在尝试扩展Java 8的Stream实现。
我有这个界面:
public interface StreamStuff<T> extends Stream<T> {
Stream<T> delegate();
default Stream<T> biggerThanFour() {
return delegate().filter(i -> ((Double)i > 4));
}
}
在我的主要方法中:
int arr [] = {1,2,3,4,5,6};
Object array [] = ((StreamStuff)Arrays
.stream(arr))
.biggerThanFour()
.toArray();
我正在尝试将Stream转换为我的界面StreamStuff,并使用我的方法。
我收到以下错误:
线程“main”中的异常java.lang.ClassCastException:java.util.stream.IntPipeline $ Head无法强制转换为StreamStuff
当我这样做时,我得到同样的错误:
StreamStuff ss = (StreamStuff)Arrays.stream(arr);
我想知道这种事情是否可能,如果是这样,我该如何实现这一目标?作为参考,我使用this article作为指导。
答案 0 :(得分:6)
您正在stream()
类上调用Arrays
,该类会创建自己的Stream
实现,而与您的任何连接都没有任何关联。您必须自己生成Stream
,或者将您在其他地方获得的流包装起来,以便这样的事情发挥作用。像这样:
int[] filtered = new StreamStuff(Arrays.stream(arr)).biggerThanFour().toArray();
但是,在您的情况下,为什么不过滤?
int[] filtered = Arrays.stream(arr).filter(i -> i > 4).toArray();
答案 1 :(得分:4)
如前所述,您可以创建自己的包装器实现:
public class MyStream<T> implements Stream<T> {
private final Stream<T> delegate;
public MyStream(Stream<T> delegate) {
this.delegate = delegate;
}
@Override
public Stream<T> filter(Predicate<? super T> predicate) {
return delegate.filter(predicate);
}
@Override
public void forEach(Consumer<? super T> action) {
delegate.forEach(action);
}
MyStream<T> biggerThanFour() {
return new MyStream<>(delegate.filter(i -> ((Double) i > 4)));
}
// all other methods from the interface
}
您必须从界面委派所有方法,因此该类将非常大。您可以考虑添加一个类StreamWrapper
,它将委托界面中的所有方法,然后让您的实际类StreamStuff
扩展StreamWrapper
。这将允许您只在StreamStuff
中使用自定义方法,而不使用其他流方法。您也可以在StreamWrapper
final中制作所有重写的方法,以避免意外覆盖它们。
然后你可以像这样使用它:
public static void main(String[] args) {
Stream<Double> orgStream = Stream.of(1.0, 3.0, 7.0, 2.0, 9.0);
MyStream<Double> myStream = new MyStream<>(orgStream);
myStream.biggerThanFour().forEach(System.out::println);
}
自定义方法返回一个新的包装器,因此您可以将调用链接到自定义方法。
请注意,您向[{1}}投射可能会抛出Double
,因此您可能会考虑将ClassCastException
替换为T
,因此将代理流限制为该特定类型
答案 2 :(得分:1)
另一种可能性是,如果您不希望将来处理所有Stream<T>
个委托和新方法,请使用带有更多包装的lambda流方法的接口:
public interface MyStream<T> {
Stream<T> stream();
static <T> MyStream<T> of(Stream<T> stream) {
return () -> stream;
}
default <U> MyStream<U> stream(Function<Stream<T>, Stream<U>> stream) {
return of(stream.apply(stream()));
}
//Watch out with Double cast. Check the type in method or restrict it via generic
default MyStream<T> biggerThanFour() {
return of(stream().filter(i -> ((Double) i > 4)));
}
//Watch out with Double cast. Check the type in method or restrict it via generic
//Another method
default MyStream<T> biggerThanFourteen() {
return of(stream().filter(i -> ((Double) i > 14)));
}
}
所以你在这里使用你的委托你的委托stream()
方法处理基本流终端方法,静态创建方法of(...)
,再一次{{1方法但使用stream(...)
作为参数来处理基本流中间方法,当然还有自定义方法,如Function<T,U>
。
所以缺点是你不能直接从biggerThanFour()
扩展(不幸的是Stream<T>
不仅有一个标准实现的默认方法)
绕过代表。
处理也是一个小缺点,但我认为在大多数情况下它很好,例如:
Stream<T>
所以列表内容是[18];)