HashMap将实体类对象设为key

记录一个最近遇到的问题,当需要对一个List的数据分组时,通常我们会使用stream的grouping by方法,它通常会将List按某个字段或属性值分组,然后返回一个Map<String, List>结构类型。

但有些时候你需要对多个字段分组,这时候有两种解决办法,第一种可以继续使用grouping by方法,对两个字段进行拼接,例如:

        Map<String, List<BillReceiptQueryDto>> map = temp.stream()
                .collect(Collectors.groupingBy(o -> o.getCustomerId() + "##" + o.getMonthYear()));

但有时候你就是不想用这种看起来有点简陋的写法,这就回到了标题,将实体类对象设置为HashMap的key。

我创建了一个实体类,其中包含3个我想要分组的字段,因为我不想##连接3个字段看起来太丑了。很容易想象,如果只有get set方法那大概率在你put进map里之后,下次遇到3个字段完全相同的实体类还是会当作新key被put进去而不是加入旧的组里。

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;
    }

   
}

如下我创建了一个简单的测试方法,将3个值都赋值相同的两个对象先后作为key put、containsKey,校验后发现输出false,和预料中一样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 + '\'' +
                '}';
    }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容