If you need this, you shouldn't use forEach, but one of the other methods available on streams; which one, depends on what your goal is.
For example, if the goal of this loop is to find the first element which matches some predicate:
Optional<SomeObject> result =
someObjects.stream().filter(obj -> some_condition_met).findFirst();
(Note: This will not iterate the whole collection, because streams are lazily evaluated - it will stop at the first object that matches the condition).
If you just want to know if there's an element in the collection for which the condition is true, you could use anyMatch:
boolean result = someObjects.stream().anyMatch(obj -> some_condition_met);
Answer from Jesper on Stack OverflowIf you need this, you shouldn't use forEach, but one of the other methods available on streams; which one, depends on what your goal is.
For example, if the goal of this loop is to find the first element which matches some predicate:
Optional<SomeObject> result =
someObjects.stream().filter(obj -> some_condition_met).findFirst();
(Note: This will not iterate the whole collection, because streams are lazily evaluated - it will stop at the first object that matches the condition).
If you just want to know if there's an element in the collection for which the condition is true, you could use anyMatch:
boolean result = someObjects.stream().anyMatch(obj -> some_condition_met);
A return in a lambda equals a continue in a for-each, but there is no equivalent to a break. You can just do a return to continue:
someObjects.forEach(obj -> {
if (some_condition_met) {
return;
}
})
java - how to break from a forEach method using lambda expression - Stack Overflow
java - How to break from forEach loop when exception occur - Stack Overflow
terminate or break java 8 stream loop - Stack Overflow
Is there a way to exit a forEach loop early?
Videos
Stream.forEach is not a loop and it's not designed for being terminated using something like break. If the stream is a parallel stream the lambda body could be executed on different threads at the same time (not easy to break that and it could easily produce incorrect results).
Better use a iterator with a while loop:
Iterator<BuyOrderType> iter = market.buyOrders() // replace BuyOrderType with correct type here
.stream()
.filter(buyOrder -> buyOrder.price >= sellOrder.price)
.sorted(BY_ASCENDING_PRICE).iterator();
while (iter.hasNext()) {
BuyOrderType buyOrder = iter.next() // replace BuyOrderType with correct type here
double tradeVolume = Math.min(buyOrder.quantity, sellOrder.quantity);
double price = buyOrder.price;
buyOrder.quantity -= tradeVolume;
sellOrder.quantity -= tradeVolume;
Trade trade = new Trade.Builder(market, price, tradeVolume, Trade.Type.SELL).build();
CommonUtil.convertToJSON(trade);
if (sellOrder.quantity == 0) {
System.out.println("order fulfilled");
break;
}
}
Well, there is no method to do this in the stream api, (as far as i know).
But if you really need it, you can use an Exception.
EDIT: For the people giving -1 to this answer I'm not advertising this as an approach one should follow, it's just an option for the cases where you need it, and it does answer the question.
public class BreakException extends RuntimeException {...}
try {
market.buyOrders()
.stream()
.filter(buyOrder -> buyOrder.price >= sellOrder.price)
.sorted(BY_ASCENDING_PRICE)
.forEach((buyOrder) -> {
double tradeVolume = Math.min(buyOrder.quantity, sellOrder.quantity);
double price = buyOrder.price;
buyOrder.quantity -= tradeVolume;
sellOrder.quantity -= tradeVolume;
Trade trade = new Trade.Builder(market, price, tradeVolume, Trade.Type.SELL).build();
CommonUtil.convertToJSON(trade);
if (sellOrder.quantity == 0) {
System.out.println("order fulfilled");
throw new BreakException()
}
});
} catch (BreakException e) {
//Stoped
}
One scenario where I choose a for loop over the forEach() method is when I want to break out of a loop early. Imagine I had a longer list of animals and as soon as I found one that matches some criteria, I want to perform some action. If I used forEach(), it would iterate over every single animal resulting in unnecessary iterations, potentially causing performance issues depending on how long the array is. With a for loop, you have the ability to break out early and stop the loop from continuing.
https://davidtang.io/2016/07/30/javascript-for-loop-vs-array-foreach.html
I like using the continue and break statements in my for each loops in Java. My CTO, doesn't like them, and suggests that "used outside of a switch statement, it gives you multiple return points from a block of code, and it – gives you GOTO like functionality". Are there any suggestions of arguing points that I can make, to defend this position... or is he right?
Use a label on the outermost loop, and include this label in the break statement when you want to jump out of all the loops. In the example below, I've modified your code to use the label OUTERMOST:
String valueFromObj2 = null;
String valueFromObj4 = null;
OUTERMOST: for(Object1 object1: objects){
for(Object2 object2: object1){
//I get some value from object2
valueFromObj2 = object2.getSomeValue();
for(Object3 object3 : object2){
for(Object4 object4: object3){
//Finally I get some value from Object4.
valueFromObj4 = object4.getSomeValue();
//Compare with valueFromObj2 to decide either to break all the foreach loop
if( compareTwoVariable(valueFromObj2, valueFromObj4 )) {
break OUTERMOST;
}
}//fourth loop ends here
}//third loop ends here
}//second loop ends here
}//first loop ends here
Extract all the loops into the function and use return.