我有一个对象
public class Sample {
private String Id;
...
private String acct;
private BigDecimal amt1;
private BigDecimal amt3;
}
我有一个列表
Id | acct | amt1 | amt2
1 | 1111 | 0.50 | 0.50
2 | 1112 | 0.50 | 0.50
我想对列表
中的amt1和amt2求和Map<Object, Sample> map = collectedTxs.stream()
.collect(Collectors.toMap(
f -> f.getAcct(),
Function.identity(),
(s, a) -> new Sample(
s.getId(),
s.getAcct(),
s.getAmt1().add(a.getAmt1()),
s.getAmt2().add(a.getAmt2()),
), LinkedHashMap::new));
有更好的方法吗?我不想把结果重新赋值给另一个Sample对象。
我不想将结果重新分配给另一个Sample对象。
流用于映射值。在流环境之外修改现有状态是不明智的,因为它可能在某些情况下导致数据不一致。但是您仍然可以使用Java 8+ map特性非常有效地完成此任务。(流并不总是最好或最有效的操作数据的方式。使用循环没有任何问题。)
我是这样做的。下面是类定义,唯一的变化是。
- 一个静态复制方法,返回一个被复制的实例(根据m.c.o nemperor的建议)。
- 添加值并返回当前实例的add方法。
static class Sample {
private String Id;
private String acct;
private BigDecimal amt1;
private BigDecimal amt2;
public Sample(String id, String acct, BigDecimal amt1,
BigDecimal amt2) {
Id = id;
this.acct = acct;
this.amt1 = amt1;
this.amt2 = amt2;
}
public Sample(Sample sample) {
this(sample.Id, sample.acct,sample.amt1,sample.amt2);
}
public static Sample copyOf(Sample s) {
return new Sample(s.Id, s.acct, s.amt1,s.amt2);
}
public Sample add(Sample sample) {
amt1 = amt1.add(sample.amt1);
amt2 = amt2.add(sample.amt2);
return this;
}
// other getters and setters
public void setId(String id) {
Id = id;
}
public void setAcct(String acct) {
this.acct = acct;
}
public void setAmt1(BigDecimal amt1) {
this.amt1 = amt1;
}
public void setAmt2(BigDecimal amt2) {
this.amt2 = amt2;
}
public String getId() {
return Id;
}
public String getAcct() {
return acct;
}
public BigDecimal getAmt1() {
return amt1;
}
public BigDecimal getAmt2() {
return amt2;
}
@Override
public String toString() {
return String.format("[%s, %s, %s, %s]", Id, acct, amt1,
amt2);
}
}
List<Sample> collectedTxs = List.of(
new Sample("1", "1111", new BigDecimal(".50"),
new BigDecimal(".50")),
new Sample("2", "1112", new BigDecimal(".50"),
new BigDecimal(".50")),
new Sample("2", "1112", new BigDecimal("1.50"),
new BigDecimal("2.50")),
new Sample("1", "1111", new BigDecimal("4.50"),
new BigDecimal("8.50")));
流程
- 遍历帐户列表。
- ,并使用合并方法合并相同的帐户。
- 帐号为key
s
是每个帐户的第一个遇到实例。- 和
BiFunction
通过添加使用方法引用 将它们组合在一起
Map<String,Sample> map = new HashMap<>();
for (Sample s : collectedTxs) {
map.merge(s.getAcct(), s, Sample::add);
}
map.forEach((k,v)-> System.out.println(k + " " + v);
打印
1112 [2, 1112, 2.00, 3.00]
1111 [1, 1111, 5.00, 9.00]
这是原始数据。注意,迭代中遇到的第一个帐户被更改了。
collectedTxs.forEach(System.out::println);
[1, 1111, 5.00, 9.00]
[2, 1112, 2.00, 3.00]
[2, 1112, 1.50, 2.50]
[1, 1111, 4.50, 8.50]
如果您想保留原始实例。然后在映射构造中进行以下更改。
map.merge(s.getAcct(), Sample.copyOf(s), Sample::add);