terminate or break java 8 stream loop

java, java-8, java-stream, loops

Solution

`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;
    }
}

Problem

I have a java 8 stream loop with the following content: ``` void matchSellOrder(Market market, Order sellOrder) { System.out.println("selling " + market.pair() + " : " + sellOrder); 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"); // break loop there } }); } ``` How can I break out of loop when some condition is met? Whats the right way to close stream anyway? UPDATE I was misusing streams tecnique assuming that it is a loop, it is not designed for that. Here's the code I've ended up using answer provided below: ``` List<Order> applicableSortedBuyOrders = market.buyOrders() .stream() .filter(buyOrder -> buyOrder.price >= sellOrder.price) .sorted(BY_ASCENDING_PRICE) .collect(toList()); for(Order buyOrder : applicableSortedBuyOrders){ 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.printAsJSON(trade); if (sellOrder.quantity == 0) { System.out.println("order fulfilled"); break; } } ```

Original source

Related problems