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

时间:2014-06-11 12:12:16

标签: 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);

我上线了

 HashMap<String, Object>[] filesArr = imagesStream.toArray(HashMap[]::new);

例外

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)

我无法理解,bug在哪里。什么意味着这个例外,以及在什么情况下可以投掷?

1 个答案:

答案 0 :(得分:4)

似乎您的getPreviewImagesURLsList()尽管名称正在返回StreamStream只能使用一次,因此您必须确保每次getPreviewImagesURLsList()的调用都会返回一个新的Stream

或者更好的是,让它按名称建议返回List,让调用者在其上调用stream()

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

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);