Java - java.lang.IllegalStateException:源已消耗或关闭

Art*_*hur 3 java java-8 java-stream

我有一些代码:

    Stream<String> previewImagesURLsList = uploadedVideoItemObj.getPreviewImagesURLsList().parallel();

    Stream<HashMap<String, Object>> imagesStream = previewImagesURLsList
            .map(new Function<String, HashMap<String, Object>>() {
                @Override
                public HashMap<String, Object> apply(String fileName) {
                    HashMap<String, Object> m = new HashMap<>();
                    m.put("preview_file", fileName);
                    m.put("parent_id", gotId);
                    return m;
                }
            });

    HashMap<String, Object>[] filesArr = imagesStream.toArray(HashMap[]::new);
Run Code Online (Sandbox Code Playgroud)

我上线了

 HashMap<String, Object>[] filesArr = imagesStream.toArray(HashMap[]::new);
Run Code Online (Sandbox Code Playgroud)

一个例外

java.lang.IllegalStateException: source already consumed or closed
    at java.util.stream.AbstractPipeline.sourceSpliterator(AbstractPipeline.java:455)
    at java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:255)
    at java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:438)
    at my.site.objects.videoitems.uploadedVideoItems.dao.impl.JdbcUploadedVideoItemDAO.insert(JdbcUploadedVideoItemDAO.java:79)
    at my.site.processors.files.threads.ServerUploadedFileProcessor.processFileServer(ServerUploadedFileProcessor.java:53)
    at my.site.processors.files.threads.ServerUploadedFileProcessor.call(ServerUploadedFileProcessor.java:28)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Run Code Online (Sandbox Code Playgroud)

看不懂,bug在哪里。这个异常是什么意思,在什么情况下可以抛出?

Hol*_*ger 5

看来你getPreviewImagesURLsList()正在返回一个Stream尽管它的名字。AStream只能使用一次,因此您必须确保每次调用都getPreviewImagesURLsList()返回一个新的Stream.

或者更好的是,正如其名称所暗示的那样,让它返回List并让调用者调用stream()它。

顺便说一句,使用Streams 的通常方法是链接方法调用,而不是将中间结果存储在变量中,以避免错误地多次使用这些变量:

HashMap<String, Object>[] filesArr =
  uploadedVideoItemObj.getPreviewImagesURLsList().parallel()
  // or better if getPreviewImagesURLsList() was returning a List:
  // uploadedVideoItemObj.getPreviewImagesURLsList().parallelStream()
  .map(fileName -> {
    HashMap<String, Object> m = new HashMap<>();
    m.put("preview_file", fileName);
    m.put("parent_id", gotId);
    return m;
  }).toArray(HashMap[]::new);
Run Code Online (Sandbox Code Playgroud)