使用 Java Stream API 以声明方式重写创建和填充 Map 的命令式代码
Rewrite imperative code of creating and populating Map in a declarative way using Java Stream API
我有这段代码:
Map<String, BillingAccount> billingAccountsMap = new HashMap<>();
for (BillingAccount ba : billingAccounts) {
if (ba.getBillingAccountIdentifier() != null && ba.getBillingAccountIdentifier().getIdentifier() != null) {
billingAccountsMap.put(ba.getBillingAccountIdentifier().getIdentifier(), ba);
}
}
我只想用 Java Stream API 和 collect(Collectors.toMap())
以功能方式重写它,但我对 null
情况有点困惑。
我正在使用 Java 11.
您可以使用 filter()
operation and then apply collect
by passing a built-in collector Collectors.toMap()
过滤掉可空值:
Map<String, BillingAccount> billingAccountsById = billingAccounts.stream()
.filter(account -> Objects.nonNull(account.getBillingAccountIdentifier()))
.filter(account -> Objects.nonNull(account.getBillingAccountIdentifier().getIdentifier()))
.collect(Collectors.toMap(
account -> account.getBillingAccountIdentifier().getIdentifier(), // keyMapper
Function.identity())); // valueMapper
请注意,对于这种方法,每个标识符都必须是唯一的。否则,您需要提供 mergeFunction
作为第三个参数来解析映射到同一键的值。
使用 Collectors.toMap(..)
将项目流转换为地图,并使用 filter()
删除不需要的项目。在你的情况下:
var billingAccountsMap = billingAccounts.stream()
.filter(ba -> ba.getBillingAccountIdentifier() != null)
.filter(ba -> ba.getBillingAccountIdentifier().getIdentifier() != null)
.collect(Collectors.toMap(ba -> ba.getBillingAccountIdentifier().getIdentifier(), ba -> ba));
查看此answer了解更多信息。
Map<String, BillingAccount> billingAccountsMap = billingAccounts.stream()
.filter(ba -> ba.getBillingAccountIdentifier() != null
&& ba.getBillingAccountIdentifier().getIdentifier() != null)
.collect(Collectors.toMap(ba -> ba.getBillingAccountIdentifier().getIdentifier(), ba -> ba));
您可以流式传输 BillingAccount
的 List
,然后使用聚合操作 filter
确保每个 BillingAccount
及其嵌套字段不为空short-circuited 条件。最后,收集结果,其中每个键是 BillingAccount
的标识符,而对应的值是对象本身。
Map<String, BillingAccount> billingAccountsMap = billingAccounts.stream()
.filter(ba -> Objects.nonNull(ba)
&& Objects.nonNull(ba.getBillingAccountIdentifier())
&& Objects.nonNull(ba.getBillingAccountIdentifier().getIdentifier()))
.collect(Collectors.toMap(ba -> ba.getBillingAccountIdentifier().getIdentifier(), Function.identity()));
您可以使用 groupingBy
一旦 filter
应用空检查:
billingAccounts.stream()
.filter(ba -> ba.getBillingAccountIdentifier() != null
&& ba.getBillingAccountIdentifier().getIdentifier() != null)
.collect(Collectors.groupingBy(x -> x.getBillingAccountIdentifier().getIdentifier()));
我有这段代码:
Map<String, BillingAccount> billingAccountsMap = new HashMap<>();
for (BillingAccount ba : billingAccounts) {
if (ba.getBillingAccountIdentifier() != null && ba.getBillingAccountIdentifier().getIdentifier() != null) {
billingAccountsMap.put(ba.getBillingAccountIdentifier().getIdentifier(), ba);
}
}
我只想用 Java Stream API 和 collect(Collectors.toMap())
以功能方式重写它,但我对 null
情况有点困惑。
我正在使用 Java 11.
您可以使用 filter()
operation and then apply collect
by passing a built-in collector Collectors.toMap()
过滤掉可空值:
Map<String, BillingAccount> billingAccountsById = billingAccounts.stream()
.filter(account -> Objects.nonNull(account.getBillingAccountIdentifier()))
.filter(account -> Objects.nonNull(account.getBillingAccountIdentifier().getIdentifier()))
.collect(Collectors.toMap(
account -> account.getBillingAccountIdentifier().getIdentifier(), // keyMapper
Function.identity())); // valueMapper
请注意,对于这种方法,每个标识符都必须是唯一的。否则,您需要提供 mergeFunction
作为第三个参数来解析映射到同一键的值。
使用 Collectors.toMap(..)
将项目流转换为地图,并使用 filter()
删除不需要的项目。在你的情况下:
var billingAccountsMap = billingAccounts.stream()
.filter(ba -> ba.getBillingAccountIdentifier() != null)
.filter(ba -> ba.getBillingAccountIdentifier().getIdentifier() != null)
.collect(Collectors.toMap(ba -> ba.getBillingAccountIdentifier().getIdentifier(), ba -> ba));
查看此answer了解更多信息。
Map<String, BillingAccount> billingAccountsMap = billingAccounts.stream()
.filter(ba -> ba.getBillingAccountIdentifier() != null
&& ba.getBillingAccountIdentifier().getIdentifier() != null)
.collect(Collectors.toMap(ba -> ba.getBillingAccountIdentifier().getIdentifier(), ba -> ba));
您可以流式传输 BillingAccount
的 List
,然后使用聚合操作 filter
确保每个 BillingAccount
及其嵌套字段不为空short-circuited 条件。最后,收集结果,其中每个键是 BillingAccount
的标识符,而对应的值是对象本身。
Map<String, BillingAccount> billingAccountsMap = billingAccounts.stream()
.filter(ba -> Objects.nonNull(ba)
&& Objects.nonNull(ba.getBillingAccountIdentifier())
&& Objects.nonNull(ba.getBillingAccountIdentifier().getIdentifier()))
.collect(Collectors.toMap(ba -> ba.getBillingAccountIdentifier().getIdentifier(), Function.identity()));
您可以使用 groupingBy
一旦 filter
应用空检查:
billingAccounts.stream()
.filter(ba -> ba.getBillingAccountIdentifier() != null
&& ba.getBillingAccountIdentifier().getIdentifier() != null)
.collect(Collectors.groupingBy(x -> x.getBillingAccountIdentifier().getIdentifier()));