Java 8 Stream - 抛出流已经被操作或关闭

时间:2016-03-17 01:21:55

标签: java java-8 java-stream

我想在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);

2 个答案:

答案 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()));
    }