问题描述
此问题是帖子的扩展:通过返回多个返回值来进行Java 8分组字段.
This question is an extension to the post: Java 8 groupingby with returning multiple field.
对于相同的问题,如何返回Customer
的列表?例如,它应该返回:
For the same problem, how do you return a list of Customer
? For example, it should return:
Customer("A",4500,6500)
Customer("B",3000,3500)
Customer("C",4000,4500)
如果您想将Map<String, Customer>
作为结果集+1,
推荐答案
@Pankaj Singhal的帖子是正确的主意.但是,我会将合并逻辑提取到其自己的函数中,例如在Customer
类中,您将具有这样的功能:
@Pankaj Singhal's post is the right idea if you want a Map<String, Customer>
as the result set +1. However, I would extract the merging logic into its own function e.g. in the Customer
class you would have a function as such:
public static Customer merge(Customer first, Customer second) {
first.setTotal(first.getTotal() + second.getTotal());
first.setBalance(first.getBalance() + second.getBalance());
return first;
}
然后,流查询将变为:
Map<String, Customer> retObj =
listCust.stream()
.collect(Collectors.toMap(Customer::getName, Function.identity(), Customer::merge));
-
listCust.stream()
创建流对象,即Stream<Customer>
. -
collect
对以下元素执行可变的归约运算使用提供的Collector
. -
toMap
是提供的收集器,toMap
方法提取键Customer::getName
和值Function.identity()
,如果映射的键包含重复项,合并功能Customer::merge
用于解决冲突. listCust.stream()
creates a stream object i.e.Stream<Customer>
.collect
performs a mutable reduction operation on the elements ofthis stream using the providedCollector
.- The result of
toMap
is the provided collector, thetoMap
method extracts the keysCustomer::getName
and valuesFunction.identity()
and if the mapped keys contain duplicates, the merge functionCustomer::merge
is used to resolve collisions. - 代码更紧凑.
- 代码更具可读性.
- 合并的复杂性与流隔离开了.
将合并逻辑提取到其自身的功能中,我看到了三个好处:
There are three benefits I see with extracting the merging logic into its own function:
但是,如果您打算检索Collection<Customer>
:
if however, your intention is to retrieve a Collection<Customer>
:
Collection<Customer> result = listCust.stream()
.collect(Collectors.toMap(Customer::getName,
Function.identity(),
Customer::merge))
.values();
或List<Customer>
作为结果集,那么您要做的就是调用values()
并将其结果传递给ArrayList
构造函数:
or List<Customer>
as the result set then all you have to do is call values()
and pass the result of that to the ArrayList
constructor:
List<Customer> result = new ArrayList<>(listCust.stream()
.collect(Collectors.toMap(Customer::getName,
Function.identity(),
Customer::merge))
.values());
更新:
如果您不想改变源中的对象,则只需修改merge
函数,如下所示:
if you don't want to mutate the objects in the source then simply modify the merge
function as follows:
public static Customer merge(Customer first, Customer second) {
Customer customer = new Customer(first.getName(), first.getTotal(), first.getBalance());
customer.setTotal(customer.getTotal() + second.getTotal());
customer.setBalance(customer.getBalance() + second.getBalance());
return customer;
}
一切都保持不变.
这篇关于Java分组依据:对多个字段求和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!