我有这两个对象:
public class Service {
private String cod;
private String name;
private String table;
private String selo;
private BigDecimal value;
private BigDecimal desconto;
private BigDecimal baseCalculo;
private Integer amountExcedente;
private String descontoLei;
... G and S
}
并且
public class ServiceResumo {
private String name;
private int amount;
private BigDecimal value;
private String acao;
public ServiceResumo(String name, BigDecimal value, int amount) {
this.name = name;
this.value = value;
this.amount = amount;
}
...G and S
}
所以我有很多服务,
List<Service> servicos = new ArrayList<Service>();
servicos.add(new Service("Service A", 3,.....)); //Service A -> Name and 3 -> value
servicos.add(new Service("Service B", 4.....));
servicos.add(new Service("Service A", 2,.....));
servicos.add(new Service("Service C", 3,.....));
servicos.add(new Service("Service D", 5,.....));
servicos.add(new Service("Service A", 6,.....));
servicos.add(new Service("Service A", 8,.....));
servicos.add(new Service("Service B", 9, .....));
那么我可以在java 8中使用stream将其减少为ServiceResumo列表吗?有点像这样:
|名字|价值|金额|
服务A | 21 | 4 |
服务B | 13 | 2 |
服务C | 3 | 1 |
服务D | 5 | 1 |
答案 0 :(得分:2)
通过组合三个收藏家
,您可以获得所需的结果groupingBy
,它允许按名称等属性对元素进行分组。ServicoResumo
对象中,您需要一个能够将Service
个实例聚合到这样的ServicoResumo
实例中的收集器。您必须为此创建一个自定义收集器。groupingBy
收集器与您的自定义收集器合并的结果为Map<PropertyType,AggregationResult>
,即Map<String,ServicoResumo>
,您需要一个后处理步骤将其转换为List<ServicoResumo>
},可以通过collectingAndThen
List<ServiceResumo> result=servicos.stream()
.collect(Collectors.collectingAndThen(
Collectors.groupingBy(Service::getName,
Collector.of(()->new ServiceResumo(null, BigDecimal.ZERO, 0),
(r,s) -> {
r.setName(s.getName());
r.setValue(r.getValue().add(s.getValue()));
r.setAmount(r.getAmount()+1);
},
(r1,r2) -> {
r1.setValue(r1.getValue().add(r2.getValue()));
r1.setAmount(r1.getAmount()+r2.getAmount());
return r1;
})),
m -> new ArrayList<>(m.values())
));
groupingBy
的第一个参数,Service::getName
指定构成分组条件的属性。 collectingAndThen
的第二个参数m -> new ArrayList<>(m.values())
说明了如何将Map
转换为所需的List
。
介于两者之间的重要部分是通过Collector.of
创建的自定义收藏夹。请参阅Collector
documentation或“Mutable Reduction” section of the package documentation以了解收藏家的工作方式。