Stream has already been operated upon or closed from supplier
Look at the message closely (emphasis mine):
java.lang.IllegalStateException: stream has already been operated
upon or closed
Since there is no terminal operation in your first statement, your stream has not been closed but has been operated upon which is the reason why you are getting the error when you try to operate on it the second time.
You can change it as follows to get rid of the error:
supplierUserStream.get().sorted().sorted();
ONLINE DEMO
However, it will be a kind of hiding a potential problem e.g. if you replace the test call in main
, with the following statement, you will again get the same problem:
getStringStream(Stream.of("Hello", "World")).forEach(System.out::println);
A good way to deal with it can be as suggested by ernest_k:
It can also be resolved by keeping track of derived stream objects.
Stream stream = s.get().sorted(); stream = stream.sorted();
return stream.sorted();, to reuse those redundant sort() calls.
Demo:
import java.util.function.Supplier;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
getStringStream(Stream.of("World", "Hello", "Good morning!")).forEach(System.out::println);
}
private static Stream<String> getStringStream(Stream<String> testStream) {
Supplier<Stream<String>> supplierStringStream = () -> testStream;
Stream<String> stream = supplierStringStream.get().sorted();
return stream.sorted();
}
}
Output:
Good morning!
Hello
World
Still getting stream has already been operated upon or closed error
The problem is that your supplier isn't giving you two instances of the stream: it's giving you the same one each time. streamSupplier.get()
is no different from using lines
directly.
If you want to read two things from the stream, skip by offset
, then limit by 2, then collect to a list:
List<String> items = lines.skip(offset).limit(2).collect(Collectors.toList());
Now you can get those items from the list:
Optional<String> line = items.size() > 0 ? Optional.of(items.get(0)) : Optional.empty();
Optional<String> nextLine = items.size() > 1 ? Optional.of(items.get(1)) : Optional.empty();
java.lang.IllegalStateException: stream has already been operated upon or closed in Java while working with list
After that
Supplier<Stream<Item>> streamSupplier = ()-> itemsList;
streamSupplier.get().filter(t-> t.getItemType().equals(ItemType.GOLD))
.forEach(item->item.setPrice(item.getWeightInGrams()*2700));
The stream is closed.
So the following line
itemsList.forEach(t->System.out.println(t)
calls the foreach
terminal operation on a already closed stream . It is forbidden.
Stream supplier getting error 'stream has already been operated upon or closed'
The general problem is as Christian Ullenboom said: The stream has already been consumed. The exact location in your code is the call to resultStreamWithExpectedStatus.count()
in the method getResultsWithExpectedStatusSupplier
, as Stream.count
is a reduction/terminal operation which consumes the stream.
As stated in e.g. this answer, you cannot get the streams size without consuming it. Fix it by storing the filtered items in a collection (e.g. Collectors.toList
), querying the size there and returning the collection itself rather than the stream?
On a side note, I think you misuse Optional
a bit too much. The code could be simpler passing empty streams (or even better: pass an empty, filtered collection).
Stream has already been operated upon or closed while loop the content of a file
The stream can only be iterated through once. You're iterating it for every element in the map.
Stop using lambdas (generally, a straight .forEach
on a stream is bad java code; you're losing checked exception, control flow, and local variable transparency and you gain nothing) and the problem goes away:
static void main(String[] args) throws IOException {
var path = Paths.get(fileName);
var lines = Files.readAllLines(path);
for (var e : map.entrySet()) {
for (String line : lines) {
String cadenaWena = line.replace(caracterMal, caracterBien);
System.out.println(cadenaWena);
}
}
}
This fixes many things:
- It reads the file once instead of over and over again. Memory access is a heck of a lot faster than disk access.
- It doesn't have crazy error handling (print half of the error, toss the other half in the bin, and just keep going? That's not good code).
- It's shorter.
- It uses the proper
replace
(which replaces ALL occurrences).replaceAll
is a misnamed method that interprets the first argument as a regexp, and it clearly isn't in your case. - It doesn't use pointless lambdas and thus is more flexible.
Stream has already been operated upon or closed - Java 8
You can't operate on Streams more than once so you are better off using Collections as these can be used more than once.
Set<String> titleExclusions = ResourceUtility.contentToUtf8TreeSet("+.txt")
.stream()
.filter(item -> !item.isEmpty())
.collect(Collectors.toSet());
// uses titleExclusions
boolean noMatches = titleExclusions.stream()
.noneMatch(tittle::contains);
// uses titleExclusions again.
Note: I assume you wanted the non-blank lines from your source file instead of the sets of blank ones. filter
takes a Predicate
of what is retained rather than what is discarded.
Thank you @Holger for simplifying the second statement.
Related Topics
Eclipse 2021-09 Code Completion Not Showing All Methods and Classes
Rotating Coordinate Plane for Data and Text in Java
Java Date Format Conversion - Getting Wrong Month
Seeking Useful Eclipse Java Code Templates
Java - How to Find the Redirected Url of a Url
How to Read Integer Value from the Standard Input in Java
Abstract Class VS Interface in Java
Convert Latitude/Longitude Point to a Pixels (X,Y) on Mercator Projection
What Are Classes, References, and Objects
When Is the @JSONproperty Property Used and What Is It Used For
Convert Integer into Byte Array (Java)
How to Implement a Map with Multiple Keys
What Does the Question Mark in Java Generics' Type Parameter Mean
Http Basic Authentication in Java Using Httpclient
Jaxb: How to Marshall Map into <Key>Value</Key>
How to Fix the "Java.Security.Cert.Certificateexception: No Subject Alternative Names Present" Error