Reputation: 423
I am more famiiliar with c# and linq but I have to work on some java code, so for the sake of learning and refactoring I was wondering if I can replace a for loop that Im using twice with a stream. I have a collection with a class object and then looping thru that collection and calling a function in that class. A few lines later I am doing the same thing just callinga different function. Looking at it and with my very new and limited knoweledge of java streams I was wondering if I can refactor a bit a la linq and pull the class object and just call the function
Collection<RowProcessingHandler> rowHandlers = getRowHandlers();
for (RowProcessingHandler handler : rowHandlers) {
handler.onProcessingStarting(columnMap);
handler.onProcess(dataList);
}
Can I use a stream to get RowProcessingHandler handler and then I can just call onProcessingStarting(columnMap); and handler.onProcess(dataList); from a variable as so
RowProcessingHandler handler = rowHandlers.stream().findFirst();
Which throws an error of Incompatible types
Upvotes: 1
Views: 123
Reputation: 12292
You are doing fine, but the error originates from the fact that the stream API provides an Optional<T>
as result from findFirst()
because the stream potentially could be empty.
Optional<RowProcessingHandler> handlerOpt = rowHandlers.stream().findFirst();
if (handlerOpt.isPresent()) {
RowProcessingHandler handler = handlerOpt.get()
}
or if you are sure that there is an entry in the stream you could do:
RowProcessingHandler handler = rowHandlers.stream().findFirst().orElseThrow();
depending on what you are about to do, this API might be more fluent:
rowHandlers.stream().forEach(handler => {
handler.onProcessingStarting(columnMap);
handler.onProcess(dataList);
});
Note that the scope of variables is a bit different in comparison to for-loops. If you use a variable within a stream scope (here for example columnMap
) it must be effectively final.
Upvotes: 2