终止或破坏java 8流循环 [英] terminate or break java 8 stream loop

查看:91
本文介绍了终止或破坏java 8流循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有以下内容的java 8流循环:

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?

更新

我误用了流tecnique,假设它是一个循环,它不是为此而设计的。以下是我最终使用的答案提供的代码:

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


推荐答案

Stream.forEach 不是循环,它不是为使用 break 之类的东西终止而设计的。如果流是并行流,则lambda body可以同时在不同的线程上执行(不容易破坏,并且很容易产生不正确的结果)。

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 easyly produce incorrect results).

最好使用带有while循环的迭代器:

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

这篇关于终止或破坏java 8流循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆