【问题标题】:Convert nested foreach loop into a stream将嵌套的 foreach 循环转换为流
【发布时间】:2019-11-22 02:19:44
【问题描述】:

我正在尝试将两个foreach 循环和一个if 语句转换为一个流。

这是我要转换的内容:

for (ViewFlightRouteAirportType associatedAirportType : etopsAndNonEtopsAssociatedAirportTypes) {

    for (ViewFlightAirportDTO airport : flightRoute.getAirportsForType(associatedAirportType)) {

        if ( airportIataCode.equals(airport.getIataCode()) ) {
            addValueIfNotPresent(associatedFlights, associatedAirportType, flightData);
        }
    }
}

etopsAndNonEtopsAssociatedAirportTypes 是一个数组。

airportIataCode 是字符串

这是我写的:

Arrays.stream(etopsAndNonEtopsAssociatedAirportTypes)
                .forEach(associatedAirportType -> flightRoute.getAirportsForType(associatedAirportType)
                        .forEach(airport -> flightRoute.getAirportsForType(associatedAirportType)
                                .stream()
                                .filter(p -> p.equals(airport.getIataCode())).forEach(addValueIfNotPresent(associatedFlights,associatedAirportType,flightData);

它不需要也不起作用,但对我来说它看起来很丑。它应该是什么样子?

【问题讨论】:

    标签: java for-loop if-statement java-stream


    【解决方案1】:

    这个怎么样?我希望您的机场有一个 getViewFlightRouteAirportType() 吸气剂,这使我们更容易做到这一点,因为我们不必跟踪 etopsAndNonEtopsAssociatedAirportTypes 数组的当前类型的值:

    Arrays.stream(etopsAndNonEtopsAssociatedAirportTypes)
            .map(flightRoute::getAirportsForType)
            .flatMap(Collection::stream)
            .filter(airport -> airportIataCode.equals(airport.getIataCode()))
            .forEach(airport -> addValueIfNotPresent(associatedFlights, airport.getViewFlightRouteAirportType(), flightData));
    

    编辑:如 cmets 中所述

    for (ViewFlightRouteAirportType associatedAirportType : etopsAndNonEtopsAssociatedAirportTypes) {
        flightRoute.getAirportsForType(associatedAirportType).stream()
                .flatMap(Collection::stream)
                .filter(airport -> airportIataCode.equals(airport.getIataCode()))
                .forEach(airport -> addValueIfNotPresent(associatedFlights, associatedAirportType, flightData));
    }
    

    【讨论】:

    • 它没有吸气剂。
    • 为什么你的机场不知道它是什么类型的?
    • 它知道。它在第一个 foreach 循环中迭代。在associatedAirportType 我们得到了类型。我需要这样做。
    • 为了便于阅读,我会离开外部 for 循环。使用流会变得丑陋(您必须在 entrySets 上使用临时地图和流)
    • 你能用外部for循环粘贴整个代码吗?我很困惑。
    【解决方案2】:

    这是一个例子。由于我没有您的课程,因此我尝试以这种方式模拟它。想象ll 是您的外部 for 循环数据结构,对于其中的每个元素,您创建另一个集合并循环它。因此,基本上,我们将内部 for 循环中的这些对象列表作为一个整体集合,以便我们可以过滤它们。这就是您可以使用flatMap 的地方,它可以展平集合的集合。然后我们只需过滤并收集这些值。

    List<String> ll = new ArrayList<>();
    
    ll.stream()
            .map(el-> Arrays.asList(el))
            .flatMap(List::stream)
            .filter(el->el.equals(str))
            .collect(Collectors.toList());
    

    再次,我想提一下,这不是你的确切情况,但我认为情况类似。

    【讨论】:

    • 不,它没有帮助。您究竟需要哪些课程?我认为你不需要我的任何课程。您可以从代码中推断出的所有类型。
    • 究竟是什么没有帮助?
    • 我是流中的初学者。我无法从你的回答中推断出任何东西。
    • 我建议您阅读更多关于mapflatMapfilter 等的信息,以及这些构造如何表示隐式迭代。从技术上讲,如果您是新手并且想从传统的for 循环转换为Streams,您可能会更频繁地使用forEach 并嵌套它们。不应该是这样的。尝试阅读更多关于这些的信息。 Java 8 Lambdas: Functional Programming For The Masses 是我个人阅读和喜欢的一本好书。
    猜你喜欢
    • 2020-11-26
    • 2011-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-19
    相关资源
    最近更新 更多