Use*_*108 6 java java-8 java-stream collectors
这个问题是帖子的扩展:Java 8 groupingby with Return multiple field。
对于同样的问题,你如何返回一个列表Customer
?例如,它应该返回:
Customer("A",4500,6500)
Customer("B",3000,3500)
Customer("C",4000,4500)
Run Code Online (Sandbox Code Playgroud)
使用以下代码:
Map<String, Customer> retObj =
listCust.stream()
.collect(Collectors.groupingBy(Customer::getName,
Collector.of(
Customer::new,
(c1, c2) -> {
c1.setName(c2.getName());
c1.setTotal(c1.getTotal() + c2.getTotal());
c1.setBalance(c1.getBalance() + c2.getBalance());
},
(c3, c4) -> {
c3.setTotal(c3.getTotal() + c4.getTotal());
c3.setBalance(c3.getBalance() + c4.getBalance());
return c3;
})));
System.out.println(retObj);
System.out.println(retObj.values()); //If you want only the list of all Customers
Run Code Online (Sandbox Code Playgroud)
输出:
{
A=Customer [name=A, total=4500.0, balance=6500.0],
B=Customer [name=B, total=3000.0, balance=3500.0],
C=Customer [name=C, total=4000.0, balance=4500.0]
}
Run Code Online (Sandbox Code Playgroud)
Map<String, Customer>
如果您想要 a作为结果集 +1,@Pankaj Singhal 的帖子是正确的想法。但是,我会将合并逻辑提取到其自己的函数中,例如在Customer
类中您将拥有这样的函数:
public static Customer merge(Customer first, Customer second) {
first.setTotal(first.getTotal() + second.getTotal());
first.setBalance(first.getBalance() + second.getBalance());
return first;
}
Run Code Online (Sandbox Code Playgroud)
那么流查询将变为:
Map<String, Customer> retObj =
listCust.stream()
.collect(Collectors.toMap(Customer::getName, Function.identity(), Customer::merge));
Run Code Online (Sandbox Code Playgroud)
listCust.stream()
创建一个流对象,即Stream<Customer>
。collect
使用提供的 对此流的元素执行可变归约操作Collector
。toMap
是提供的收集器,该toMap
方法提取键 Customer::getName
和值,如果映射的键包含重复项,则使用Function.identity()
合并函数来解决冲突。Customer::merge
我认为将合并逻辑提取到其自己的函数中具有三个好处:
但是,如果您的意图是检索Collection<Customer>
:
Collection<Customer> result = listCust.stream()
.collect(Collectors.toMap(Customer::getName,
Function.identity(),
Customer::merge))
.values();
Run Code Online (Sandbox Code Playgroud)
或者List<Customer>
作为结果集,您所要做的就是调用values()
并将结果传递给ArrayList
构造函数:
List<Customer> result = new ArrayList<>(listCust.stream()
.collect(Collectors.toMap(Customer::getName,
Function.identity(),
Customer::merge))
.values());
Run Code Online (Sandbox Code Playgroud)
更新:
如果您不想改变源中的对象,则只需修改该merge
函数即可,如下所示:
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;
}
Run Code Online (Sandbox Code Playgroud)
其他一切都保持原样。
归档时间: |
|
查看次数: |
3178 次 |
最近记录: |