Java Stream:通过布尔谓词分为两个列表 [英] Java Stream: divide into two lists by boolean predicate

查看:14
本文介绍了Java Stream:通过布尔谓词分为两个列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个员工的列表.他们有 isActive 布尔字段.我想将 employees 分成两个列表:activeEmployeesformerEmployees.是否可以使用 Stream API?最复杂的方法是什么?

I have a list of employees. They have isActive boolean field. I would like to divide employees into two lists: activeEmployees and formerEmployees. Is it possible to do using Stream API? What is the most sophisticated way?

推荐答案

Collectors.partitioningBy:

Map<Boolean, List<Employee>> partitioned = 
    listOfEmployees.stream().collect(
        Collectors.partitioningBy(Employee::isActive));

结果映射包含两个列表,对应谓词是否匹配:

The resulting map contains two lists, corresponding to whether or not the predicate was matched:

List<Employee> activeEmployees = partitioned.get(true);
List<Employee> formerEmployees = partitioned.get(false);

<小时>

使用 partitioningBy 而不是 groupingBy 有几个原因(正如 胡安·卡洛斯·门多萨):


There are a couple of reasons to use partitioningBy over groupingBy (as suggested by Juan Carlos Mendoza):

首先,groupingBy 的参数是一个 Function(在这种情况下),因此有可能向它传递一个函数,它可以return null, 意味着如果该函数为任何员工返回 null,则将有第三个分区.partitioningBy 使用 Predicate,因此它只能返回 2 个分区. 这将导致抛出 NullPointerException收集器:虽然没有明确记录,但为空键显式抛出异常,大概是因为 Map.computeIfAbsent 表示如果函数返回 null,则不会记录任何映射",这意味着元素将从输出中静默删除.(感谢 lczapski 指出这一点.

Firstly, the parameter of groupingBy is a Function<Employee, Boolean> (in this case), and so there is a possibility of passing it a function which can return null, meaning there would be a 3rd partition if that function returns null for any of the employees. partitioningBy uses a Predicate<Employee>, so it can only ever return 2 partitions. which would result in a NullPointerException being thrown by the collector: whilst not documented explicitly, an exception is explicitly thrown for null keys, presumably because of the behavior of Map.computeIfAbsent that "If the function returns null no mapping is recorded", meaning elements would otherwise be dropped silently from the output. (Thanks to lczapski for pointing this out).

其次,您在结果映射中使用 partitioningBy 获得两个列表 (*);使用 groupingBy,您只能获得元素映射到给定键的键/值对:

Secondly, you get two lists (*) in the resulting map with partitioningBy; with groupingBy, you only get key/value pairs where elements map to the given key:

System.out.println(
    Stream.empty().collect(Collectors.partitioningBy(a -> false)));
// Output: {false=[], true=[]}

System.out.println(
    Stream.empty().collect(Collectors.groupingBy(a -> false)));
// Output: {}

<小时>

(*) 此行为未记录在 Java 8 Javadoc,但它是为 Java 9.

这篇关于Java Stream:通过布尔谓词分为两个列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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