我正在使用以下代码重用Stream,但得到
java.lang.IllegalStateException:流已被操作或关闭
代码
public static void main(String[] args) {
try {
String[] array = { "a", "b", "c", "d", "e" };
Stream<String> ss = Stream.of(array);
Supplier<Stream<String>> streamSupplier = () -> ss;
long count = streamSupplier.get().count();
// get new stream
streamSupplier.get().forEach(x -> System.out.println(x));
// get another new stream
System.out.println(count);
} catch (Exception e) {
e.printStackTrace();
}
}
答案 0 :(得分:4)
不要将Stream.of(array)
分配给中间变量,只需直接在Supplier
中将其返回即可:
Supplier<Stream<String>> streamSupplier = () -> Stream.of(array);
这是因为以前,您在调用supplier.get()
时总是会提供相同的 reference ,但实际上您想返回一个新的Stream
。
也正如@Eugene建议的那样,最好使用Arrays.stream()
而不是Stream.of()
。后者是varargs方法,但仅委托给前者。
此外,您可以使用Stream.peek()
方法来简化当前的方法:
long count = Arrays.stream(array)
.peek(System.out::println)
.count();
答案 1 :(得分:4)
Stream::count
是terminal操作,它将关闭Stream,因此无法继续处理任何管道。
您先创建Stream<String>
,然后再将其放入Supplier
。如果您希望供应商在每次调用时提供一个新的Stream女巫,请直接在Stream<String>
中创建Supplier
。
Supplier<Stream<String>> streamSupplier = () -> Stream.of(array);
然后streamSupplier.get()
将始终与新的Stream<Stream>
一起使用。
但是,您可以使用Stream::peek
达到相同的结果,该结果与Stream::forEach
的工作原理相同,不同的是它不会关闭Stream
而是返回相同的未修改的(@ Lino更快)。
long count = streamSupplier.get().peek(System.out::println).count();
答案 2 :(得分:1)
您遇到的异常是适当的,它告诉您需要研究的内容。来自Java 8 Stream class:
应该对流进行操作(调用中间或终端 流操作)。例如,这排除了“分叉” 流,其中相同的源提供两个或多个管道,或者 同一流的多个遍历。流实现可以 如果检测到流正在被抛出,则抛出IllegalStateException 重用。但是,由于某些流操作可能会返回它们 接收者而不是新的流对象,则可能无法 检测所有情况下的重用。
答案 3 :(得分:0)
您仍在重复使用同一流。将<local:RepeaterView x:Name="approvalsStack" ItemsSource="{Binding Approvals}">
<local:RepeaterView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Text="{Binding FullName}"/>
<Label Grid.Column="1" Text="{Binding Decision}"/>
<Label Grid.Column="2" Text="{Binding DecisionDate}"/>
</Grid>
<StackLayout>
<BoxView HeightRequest="1" Color="Gray" HorizontalOptions="FillAndExpand"/>
</StackLayout>
</StackLayout>
</ViewCell>
</DataTemplate>
</local:RepeaterView.ItemTemplate>
</local:RepeaterView>
移到供应商内部,而不是外部。