我想在stream api中实现分页。
我使用if语句来修改流,但遇到
时我很惊讶java.lang.IllegalStateException: stream has already been operated upon or closed
这是我的代码
@Override
public List<Foo> search(String[] names, Integer offset, Integer size) {
final Stream<Foo> fooStream = findAllFoos().stream();
if(offset!=null) {
fooStream
.skip(offset)
.limit(size);
}
if(ArrayUtils.isNotEmpty(names)) {
fooStream.filter(foo -> ArrayUtils.contains(names, foo.getName()));
}
final List<Foo> foos = fooStream.collect(Collectors.toList()); //this lines throws the exception, according to stacktrace
return foos;
}
这是我的Foo.class
public class Foo {
private String name;
//..setters and getters
}
以下是对该搜索方法的示例调用
fooService.search(fooNamesArray, 0, 1);
fooService.search(fooNamesArray, null, null);
答案 0 :(得分:4)
fooStream.skip(offset)
本身没有没有。它会返回 new Stream
;它不会修改fooStream
。
一般来说,您只能使用Stream
进行一项操作,但这可能会转换为另一种Stream
。
你可以做什么,虽然它仍然会让你的代码变得尴尬,但是要写fooStream = fooStream.skip(offset).limit(size)
。
答案 1 :(得分:0)
您可能希望事先添加所有验证并一次性合并所有流操作。
List<Foo> foos = fooStream.skip(offset)
.limit(size)
.filter(foo -> ArrayUtils.contains(names, foo.getName()))
.collect(Collectors.toList());
在其他情况下,您可以将每个流操作的结果转换为另一个流并对其进行操作。
Stream<Foo> skippedFooStream = Collections.<Foo>emptyList().stream();
if(offset!=null) {
skippedFooStream = fooStream
.skip(offset)
.limit(size);
}
if(ArrayUtils.isNotEmpty(names)) {
// take this into another temp stream and proceed
skippedFooStream.filter(foo -> ArrayUtils.contains(names, foo.getName()));
}