記錄一個最近遇到的問題,當(dāng)需要對一個List的數(shù)據(jù)分組時声搁,通常我們會使用stream的grouping by方法,它通常會將List按某個字段或?qū)傩灾捣纸M,然后返回一個Map<String, List>結(jié)構(gòu)類型芹枷。
但有些時候你需要對多個字段分組,這時候有兩種解決辦法莲趣,第一種可以繼續(xù)使用grouping by方法鸳慈,對兩個字段進(jìn)行拼接,例如:
Map<String, List<BillReceiptQueryDto>> map = temp.stream()
.collect(Collectors.groupingBy(o -> o.getCustomerId() + "##" + o.getMonthYear()));
但有時候你就是不想用這種看起來有點(diǎn)簡陋的寫法喧伞,這就回到了標(biāo)題走芋,將實(shí)體類對象設(shè)置為HashMap的key绩郎。
我創(chuàng)建了一個實(shí)體類,其中包含3個我想要分組的字段翁逞,因?yàn)槲也幌?#連接3個字段看起來太丑了肋杖。很容易想象,如果只有g(shù)et set方法那大概率在你put進(jìn)map里之后挖函,下次遇到3個字段完全相同的實(shí)體類還是會當(dāng)作新key被put進(jìn)去而不是加入舊的組里状植。
public class ReceiptUpdateEntity {
private Date billMonth;
private String customerId;
private String productId;
public Date getBillMonth() {
return billMonth;
}
public void setBillMonth(Date billMonth) {
this.billMonth = billMonth;
}
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
}
如下我創(chuàng)建了一個簡單的測試方法,將3個值都賦值相同的兩個對象先后作為key put怨喘、containsKey浅萧,校驗(yàn)后發(fā)現(xiàn)輸出false,和預(yù)料中一樣HashMap并沒有判斷兩個對象相同哲思。解決辦法就是重寫這個類的equals和hashCode方法洼畅,用idea自動生成就行,只有這樣才能讓HashMap在識別的時候判斷這兩個對象是相同的棚赔。
Date temp = DateUtil.convert("2023-10-01 00:00:00", DateUtil.format1);
Date temp2 = DateUtil.convert("2023-10-01 00:00:00", DateUtil.format1);
Map<ReceiptUpdateEntity, List<CustomerProductTj>> collect = new HashMap<>();
ReceiptUpdateEntity updateEntity = new ReceiptUpdateEntity();
String customerId = "123456789";
String productId = "123456798";
updateEntity.setBillMonth(temp);
updateEntity.setCustomerId(customerId);
updateEntity.setProductId(productId);
collect.put(updateEntity, null);
ReceiptUpdateEntity updateEntity2 = new ReceiptUpdateEntity();
String customerId2 = "123456789";
String productId2 = "123456798";
updateEntity2.setBillMonth(temp2);
updateEntity2.setCustomerId(customerId2);
updateEntity2.setProductId(productId2);
System.out.println(collect.containsKey(updateEntity2));
ReceiptUpdateEntity updateEntity3 = new ReceiptUpdateEntity();
String customerId3 = "123456789";
String productId3 = "";
updateEntity3.setBillMonth(temp2);
updateEntity3.setCustomerId(customerId3);
updateEntity3.setProductId(productId3);
System.out.println(collect.containsKey(updateEntity3));
// 可以在Map里使用對象作為key 但需要重寫這個對象類的equals和hashcode方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ReceiptUpdateEntity that = (ReceiptUpdateEntity) o;
return billMonth.equals(that.billMonth) && customerId.equals(that.customerId) && productId.equals(that.productId);
}
@Override
public int hashCode() {
return Objects.hash(billMonth, customerId, productId);
}
@Override
public String toString() {
return "ReceiptUpdateEntity{" +
"billMonth=" + billMonth +
", customerId='" + customerId + '\'' +
", productId='" + productId + '\'' +
'}';
}