简体   繁体   中英

Calling forEach on a stream causes java.lang.IllegalStateException

I have a program which does the following:

  1. Stores a file name in Main method

  2. Passes that file to the below method(StreamParser)from Main

  3. Method StreamParser reads that file as Stream

  4. StreamParser should return Stream

  5. In main method when I call forEach on purchaseEventStream it gives an error in line

    purchaseEventStream.forEach(purchaseEvent -> {

Exception in thread "main" java.lang.IllegalStateException: source already consumed or 
    closed
    at java.base/java.util.stream.AbstractPipeline.sourceSpliterator(AbstractPipeline.java:409)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
    at com.cognitree.internship.streamprocessing.Main.main(Main.java:22)

StreamParser Class

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;

public class StreamParser {

public Stream<PurchaseEvent> parser(String fileName) throws IOException {
    Stream<PurchaseEvent> purchaseEventStream;
    try (Stream<String> lines = Files.lines(Paths.get(fileName))) {
        purchaseEventStream= lines.map(line -> {
            String[] fields = line.split(",");
            PurchaseEvent finalPurchaseEvent = new PurchaseEvent();
            finalPurchaseEvent.setSessionId(fields[0]);
            finalPurchaseEvent.setTimeStamp(fields[1]);
            finalPurchaseEvent.setItemId(fields[2]);
            finalPurchaseEvent.setPrice(fields[3]);
            finalPurchaseEvent.setQuantity(fields[4]);
            return finalPurchaseEvent;
        });
        return purchaseEventStream;
    }
}
}

Main Class

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class Main {
public static void main(String[] args) throws IOException {
    OutputStreamWriter outputStream = new OutputStreamWriter(new 
    FileOutputStream("output1.txt"));
    String file = "/Users/mohit/intern-mohit/yoochoose-buys.dat";
    StreamParser streamParser = new StreamParser();
    List<ReportGenerator> reports = new ArrayList<>();
    PurchaseEventCount purchaseEventCount = new PurchaseEventCount();
    QuantityPerSession quantityPerSession = new QuantityPerSession();
    SessionCount sessionCount = new SessionCount();
    reports.add(purchaseEventCount);
    reports.add(sessionCount);
    reports.add(quantityPerSession);
    Stream<PurchaseEvent> purchaseEventStream = streamParser.parser(file);
    purchaseEventStream.forEach(purchaseEvent -> {
        for (ReportGenerator report : reports) {
            report.generateReports(purchaseEvent);
        }
    });
    reports.forEach(report -> {
        try {
            report.printReports(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    });
}
}

Why am i getting the error?

A stream in java is not a collection. It does not store data. You should create and return a collection from method parser() in class StreamParser and then create a stream from the returned collection.

I rewrote your StreamParser class to return a List .

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;

public class StreamParser {

    public List<PurchaseEvent> parser(String fileName) throws IOException {
        List<PurchaseEvent> purchaseEventStream = Files.lines(Paths.get(fileName))
                                                       .map(line -> {
                                                           String[] fields = line.split(",");
                                                           PurchaseEvent finalPurchaseEvent = new PurchaseEvent();
                                                           finalPurchaseEvent.setSessionId(fields[0]);
                                                           finalPurchaseEvent.setTimeStamp(fields[1]);
                                                           finalPurchaseEvent.setItemId(fields[2]);
                                                           finalPurchaseEvent.setPrice(fields[3]);
                                                           finalPurchaseEvent.setQuantity(fields[4]);
                                                           return finalPurchaseEvent;
                                                       })
                                                       .collect(Collectors.toList());
        return purchaseEventStream;
    }
}

And I changed your Main class accordingly.

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter outputStream = new OutputStreamWriter(new FileOutputStream("output1.txt"));
        String file = "/Users/mohit/intern-mohit/yoochoose-buys.dat";
        StreamParser streamParser = new StreamParser();
        List<ReportGenerator> reports = new ArrayList<>();
        PurchaseEventCount purchaseEventCount = new PurchaseEventCount();
        QuantityPerSession quantityPerSession = new QuantityPerSession();
        SessionCount sessionCount = new SessionCount();
        reports.add(purchaseEventCount);
        reports.add(sessionCount);
        reports.add(quantityPerSession);
        List<PurchaseEvent> purchaseEventStream = streamParser.parser(file);
        purchaseEventStream.forEach(purchaseEvent -> {
            for (ReportGenerator report : reports) {
                report.generateReports(purchaseEvent);
            }
        });
        reports.forEach(report -> {
            try {
                report.printReports(outputStream);
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        });
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM