为了账号安全,请及时绑定邮箱和手机立即绑定

java 8 sum field from list of object with common

java 8 sum field from list of object with common

尚方宝剑之说 2022-07-20 15:49:16
我有这个对象列表List<DetailDto> details;    @Value    public class DetailDto implements Serializable {        String category1;        Integer category2;        Integer price;        transient Integer totalPrice;    }有了这份清单[  {    "category1": "ABC",    "category2": 30,    "price": 195,    "totalPrice": null  },  {    "category1": "ABC",    "category2": 30,    "price": 195,    "totalPrice": null  },  {    "category1": "ABC",    "category2": 30,    "price": 195,    "totalPrice": null  },  {    "category1": "ABC",    "category2": 30,    "price": 390,    "totalPrice": null  },  {    "category1": "ABC",    "category2": 30,    "price": 390,    "totalPrice": null  },  {    "category1": "DEF",    "category2": 30,    "price": 455,    "totalPrice": null  },  {    "category1": "DEF",    "category2": 30,    "price": 455,    "totalPrice": null  },  {    "category1": "DEF",    "category2": 30,    "price": 455,    "totalPrice": null  },  {    "category1": "DEF",    "category2": 30,    "price": 455,    "totalPrice": null  },  {    "category1": "GHI",    "category2": 1,    "price": 18000,    "totalPrice": null  }]我想通过将字段List<DetailDto>总结为条件为的字段来制作另一个对象:pricetotalPrice字符串category1很常见整数category2很常见整数price很常见在这一点上我有这个List<List<DetailDto>> summarizedList = detail().stream()        .collect(Collectors.groupingBy(DetailDto::category1,                                       Collectors.groupingBy(DetailDto::category2,                                                             Collectors.groupingBy(DetailDto::price))))        .values()        .stream()        .flatMap(c1 -> c1.values().stream())        .flatMap(c2 -> c2.values().stream())        .collect(Collectors.toList());返回我List<List<DetailDto>>而且我不知道如何使它正确,在我尝试这个之后summarizedList.stream().map(dto -> dto.stream().reduce((x,y) -> new DetailDto(x.productCode(), x.productQt(), x.orderPrice(), Integer.sum(x.orderPrice(), y.orderPrice()).orElse(null).collect(Collectors.toList());你们能帮帮我吗?
查看完整描述

1 回答

?
白猪掌柜的

TA贡献1893条经验 获得超10个赞

这是一种可能性:使用复合键一次分组:


.collect(Collectors.groupingBy(DetailDto::key, Collectors.summarizingInt(DetailDto::getPrice)))

请参阅KeyDetailDto.java 中的定义(并注意其 eclipse 生成hashCode的equals方法):


import java.io.Serializable;


@SuppressWarnings("serial")

public class DetailDto implements Serializable {

    String category1;

    Integer category2;

    Integer price;


    transient Integer totalPrice;


    public DetailDto() {

    }




    public DetailDto(String category1, Integer category2, Integer price, Integer totalPrice) {

        super();

        this.category1 = category1;

        this.category2 = category2;

        this.price = price;

        this.totalPrice = totalPrice;

    }




    public String getCategory1() {

        return category1;

    }


    public void setCategory1(String category1) {

        this.category1 = category1;

    }


    public Integer getCategory2() {

        return category2;

    }


    public void setCategory2(Integer category2) {

        this.category2 = category2;

    }


    public Integer getPrice() {

        return price;

    }


    public void setPrice(Integer price) {

        this.price = price;

    }


    public Integer getTotalPrice() {

        return totalPrice;

    }


    public void setTotalPrice(Integer totalPrice) {

        this.totalPrice = totalPrice;

    }


    Key key() {

        return new Key(category1, category2, price);

    }


}

class Key {

    String category1;

    Integer category2;

    Integer price;


    public Key(String category1, Integer category2, Integer price) {

        super();

        this.category1 = category1;

        this.category2 = category2;

        this.price = price;

    }

    public String getCategory1() {

        return category1;

    }

    public Integer getCategory2() {

        return category2;

    }

    public Integer getPrice() {

        return price;

    }

    @Override

    public int hashCode() {

        final int prime = 31;

        int result = 1;

        result = prime * result + ((category1 == null) ? 0 : category1.hashCode());

        result = prime * result + ((category2 == null) ? 0 : category2.hashCode());

        result = prime * result + ((price == null) ? 0 : price.hashCode());

        return result;

    }

    @Override

    public boolean equals(Object obj) {

        if (this == obj)

            return true;

        if (obj == null)

            return false;

        if (getClass() != obj.getClass())

            return false;

        Key other = (Key) obj;

        if (category1 == null) {

            if (other.category1 != null)

                return false;

        } else if (!category1.equals(other.category1))

            return false;

        if (category2 == null) {

            if (other.category2 != null)

                return false;

        } else if (!category2.equals(other.category2))

            return false;

        if (price == null) {

            if (other.price != null)

                return false;

        } else if (!price.equals(other.price))

            return false;

        return true;

    }

}

Main.java


import java.io.IOException;

import java.util.IntSummaryStatistics;

import java.util.Map;

import java.util.stream.Collectors;

import java.util.stream.Stream;


import com.fasterxml.jackson.core.JsonProcessingException;

import com.fasterxml.jackson.databind.ObjectMapper;

import com.fasterxml.jackson.databind.ObjectWriter;


public class Main {


    public static void main(String[] args) throws IOException {

        DetailDto[] values = new ObjectMapper().readerFor(DetailDto[].class)

                .readValue(Main.class.getResourceAsStream("data.json"));

//      for (DetailDto dto : values) {

//          display(dto);

//      }


        Map<Key, IntSummaryStatistics> res = Stream.of(values)

                .collect(Collectors.groupingBy(DetailDto::key, Collectors.summarizingInt(DetailDto::getPrice)));


        Stream<DetailDto> agg = res.entrySet().stream().map(e -> new DetailDto(e.getKey().category1,

                e.getKey().category2, e.getKey().price, (int) e.getValue().getSum()));


        agg.forEach(Main::display);


    }


    protected static void display(DetailDto dto) {

        final ObjectWriter json = new ObjectMapper().writerFor(DetailDto.class).withDefaultPrettyPrinter();

        try {

            System.out.println(json.writeValueAsString(dto));

        } catch (JsonProcessingException e) {

            throw new RuntimeException(e);

        }

    }

}


查看完整回答
反对 回复 2022-07-20
  • 1 回答
  • 0 关注
  • 80 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信