【问题标题】:How to filter a stream based on the boolean of an object如何根据对象的布尔值过滤流
【发布时间】:2021-08-29 14:09:28
【问题描述】:

我有一个对象(汽车)列表,我想将所有工作的汽车放在列表中的第一位,然后将非工作的汽车放在列表中。

汽车对象有一个等于true 或false 的isWorking() getter。

cars.stream()
    .filter(x->x.isWorking())
    .collect(Collectors.toList());
System.out.println("Working Cars First" + car);

【问题讨论】:

    标签: list java-stream


    【解决方案1】:

    Boolean 有一个自然的顺序,就像任何其他的原语包装类一样。假在真之前。既然你想要isWorking()首先返回true的那些,我们需要反转条件。

    car = car.stream()
            .sorted(Comparator.comparing(x -> ! x.isWorking()))
            .collect(Collectors.toList());
    System.out.println("Working Cars First: " + car);
    

    正如 Nikolas Charalambidis 在评论中指出的那样,Comparator 也可以写成 Comparator.comparing(Car::isWorking).reversed(),这可能感觉更自然,更符合通常的比较器。

    【讨论】:

    • 这太棒了!为了清楚起见,我宁愿使用这个比较器:Comparator.comparing(Car::isWorking).reversed()(我的个人喜好)。
    • 谢谢,@Nikolas。我曾考虑过(你不必相信我 :-) 你说服我在答案中值得一提,所以我进行了编辑。
    【解决方案2】:

    使用 Stream API 收集器执行分组到地图Map<Boolean, List<Car>> 中,并将所有列表连续添加到一个新列表中,从而使“工作”汽车首先出现。或者更好的是,使用与分组相同的分区,但基于布尔键,由于给定的Predicate,导致映射具有两个条目。这是一些代码:

    List<Car> cars = ...
    Map<Boolean, List<Car>> resultMap = cars.stream()
                .collect(Collectors.partitioningBy(Car::isWorking));
    
    List<Car> orderedCars = new ArrayList<>();
    orderedCars.addAll(resultMap.get(true));
    orderedCars.addAll(resultMap.get(false));
    

    ...或使用collectingAndThencollector 的单个语句:

    List<Car> orderedCars = cars.stream()
        .collect(
            Collectors.collectingAndThen(
                Collectors.partitioningBy(Car::isWorking),
                map -> Stream.of(map.get(true), map.get(false))
                             .flatMap(List::stream)
                             .collect(Collectors.toList())));
    

    这个解决方案在时间复杂度方面超过了排序,因为分区收集器应该在线性时间内处理列表,但是,我们需要在内存中存储更多的对象,这可能不适合大型对象的列表。

    【讨论】:

    • 谢谢,@OleV.V。为了提高它。这不仅是正确的,而且还展示了另一种同样好的方法。
    • @OleV.V. - 那太棒了!您为崇高的事业采取主动并取得了成功。太棒了!
    猜你喜欢
    • 2019-10-09
    • 2011-02-05
    • 2013-09-11
    • 1970-01-01
    • 2021-05-18
    • 1970-01-01
    • 1970-01-01
    • 2020-05-15
    • 2018-04-07
    相关资源
    最近更新 更多