简体   繁体   English

如何使用流重写嵌套列表的查找功能

[英]How to rewrite find function of nested lists using streams

Given a List<Unicorn> , with each unicorn containing a List<Rider> , return the unicorn and the latest rider info for a subset of riders. 给定一个List<Unicorn> ,每个独角兽都包含一个List<Rider> ,返回该独角兽和一部分骑手的最新骑手信息。

I've written this as such: 我这样写:

static Optional<ImmutablePair<Unicorn, Rider>> findLatestExperiencedRiderInfo(
        final List<Unicorn> unicorns) {

    Rider latestExperiencedRider = null;
    Unicorn unicornOfLatestExperiencedRider = null;
    long latestRideTime = 0L;

    for (final Unicorn unicorn : unicorns) {
        for (final Rider rider : unicorn.getRiders()) {
            if (rider.getType() == Rider.Type.EXPERIENCED) {
                final long time = rider.getRideTime();
                if (time > latestRideTime) {
                    latestRideTime = time;
                    latestExperiencedRider = rider;
                    unicornOfLatestExperiencedRider = unicorn;
                }
            }
        }
    }

    return latestExperiencedRider == null
            ? Optional.empty()
            : Optional.of(new ImmutablePair<>(
                    unicornOfLatestExperiencedRider,
                    latestExperiencedRider));
}

I was hoping for a more succinct version, possibly using streams (or just written differently). 我希望有一个更简洁的版本,可能使用流(或只是用不同的方式编写)。 What would be your suggestions? 您有什么建议?

Here's a stream version 这是流媒体版本

unicorns.stream()
        .flatMap(unicorn -> unicorn.getRiders()
                .stream()
                .filter(rider -> rider.getType() == Rider.Type.EXPERIENCED)
                .map(rider -> new AbstractMap.SimpleEntry<>(unicorn, rider)))
        .max(Comparator.comparingLong(entry -> entry.getValue().getRideTime()))
        .map(entry -> new ImmutablePair<>(entry.getKey(), entry.getValue()));

The flatMap part flattens all the Riders into AbstractMap.SimpleEntry s each containing a Rider and the Unicorn it was part of. flatMap部分将所有Riders展平为AbstractMap.SimpleEntry每个都包含一个Rider和它所属的Unicorn Then we get the max entry by comparing two Rider 's rideTime . 然后我们通过比较两个RiderrideTime获得最大条目。 If present, we create the ImmutablePair result else will be Optional.empty 如果存在,我们创建ImmutablePair结果,否则为Optional.empty

Maybe something like this, you can add the required null checks.. 也许像这样,您可以添加所需的null检查。

// This is your rider..
final Optional<Rider> aRider = unicorns.stream()
                                       .flatMap(unicorn -> unicorn.getRiders().stream())
                                       .filter(rider -> rider.type == Rider.Type.EXPERIENCED)
                                       .max(Comparator.comparingLong(Rider::getRideTime));

 // This is your unicorn..
final Optional<Unicorn> any = unicorns.stream()
                                      .filter(unicorn -> unicorn.getRiders().contains(aRider.get()))
                                      .findAny();

You can also keep a reference to a Unicorn in the Rider I guess so you do not need to search your unicorn once you have your a rider. 我猜您也可以在Rider保留对Unicorn的引用,因此一旦有了骑手,就无需搜索独角兽。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM