Lia*_*ris 6 java casting java-8 java-stream
我正在尝试扩展Java 8的Stream实现.
我有这个界面:
public interface StreamStuff<T> extends Stream<T> {
Stream<T> delegate();
default Stream<T> biggerThanFour() {
return delegate().filter(i -> ((Double)i > 4));
}
}
Run Code Online (Sandbox Code Playgroud)
在我的主要方法:
int arr [] = {1,2,3,4,5,6};
Object array [] = ((StreamStuff)Arrays
.stream(arr))
.biggerThanFour()
.toArray();
Run Code Online (Sandbox Code Playgroud)
我正在尝试将Stream转换为我的接口StreamStuff,并使用我的方法.
我收到以下错误:
线程"main"中的异常java.lang.ClassCastException:java.util.stream.IntPipeline $ Head无法强制转换为StreamStuff
当我这样做时,我得到同样的错误:
StreamStuff ss = (StreamStuff)Arrays.stream(arr);
我想知道这种事情是否可能,如果是这样,我该如何实现这一目标?作为参考,我有点使用这篇文章作为指导.
您呼叫stream()
的Arrays
类,它创建自己Stream
没有给你任何的连接实现.您必须Stream
自己制作,或者将您在其他地方获得的流包装起来,以便使这样的事情发挥作用.像这样的东西:
int[] filtered = new StreamStuff(Arrays.stream(arr)).biggerThanFour().toArray();
Run Code Online (Sandbox Code Playgroud)
但是,在你的情况下,你为什么不过滤?
int[] filtered = Arrays.stream(arr).filter(i -> i > 4).toArray();
Run Code Online (Sandbox Code Playgroud)
如前所述,您可以创建自己的包装器实现:
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
}
Run Code Online (Sandbox Code Playgroud)
您将不得不委托接口中的所有方法,因此该类将非常大。您可能会考虑添加一个类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);
}
Run Code Online (Sandbox Code Playgroud)
自定义方法返回一个新的包装器,以便您可以将调用链接到自定义方法。
请注意,您的强制转换Double
可能会抛出,ClassCastException
因此您可能会考虑将 generic 替换T
为Double
,从而将委托流限制为该特定类型。