英文:
How to merge duplicated property value and sum their other property - java
问题
以下是翻译好的部分:
public class ContrastItem {
    private String range;
    private Long contrast;
}
期望的结果:
[{
    "contrast": 4,
    "range": "00:00:00-00:59:59"
},
{
    "contrast": 0,
    "range": "01:00:00-01:59:59"
}]
我尝试使用流进行映射,使用groupby和summingLong,但无法理解如何解决它(不知道我在做什么):
mylist.stream()
    .collect(Collectors.groupingBy(
        ContrastItem::getRange, Collectors.summingLong(ContrastItem::getContrast)))
    .entrySet().stream().map().collect(Collectors.toList());
英文:
I have list of this object, wanted to sum duplicated item's contrast and remove duplicates.
public class ContrastItem {
    private String range;
    private Long contrast;
}
            [{
                "contrast": 3,
                "range": "00:00:00-00:59:59"
            },
            {
                "contrast": 1,
                "range": "00:00:00-00:59:59"
            },
            {
                "contrast": 0,
                "range": "01:00:00-01:59:59"
            },
            {
                "contrast": 0,
                "range": "01:00:00-01:59:59"
            }]
Expected:
            [{
                "contrast": 4,
                "range": "00:00:00-00:59:59"
            },
            {
                "contrast": 0,
                "range": "01:00:00-01:59:59"
            }]
I have tried stream mapping the list with groupby and summingLong but could't wrap around my head to solve it.(don't know what i'm doing)
mylist.stream()
.collect(Collectors.groupingBy(
ContrastItem::getRange,Collectors.summingLong(ContrastItem::getContrast)))
.entrySet().stream().map().collect(Collectors.toList());
答案1
得分: 0
您的方法非常接近,
itemList.stream()
    .collect(Collectors.groupingBy(
        ContrastItem::getRange,
        Collectors.summingLong(ContrastItem::getContrast)
    ));
这段代码创建了一个映射 {01:00:00-01:59:59=0, 00:00:00-00:59:59=4},
然后您需要将其转换为 ContrastItem 列表:
public static void main(String[] args) {
    List<ContrastItem> itemList = new ArrayList<>();
    itemList.add(new ContrastItem("00:00:00-00:59:59", 3L));
    itemList.add(new ContrastItem("00:00:00-00:59:59", 1L));
    itemList.add(new ContrastItem("01:00:00-01:59:59", 0L));
    itemList.add(new ContrastItem("01:00:00-01:59:59", 0L));
    List<ContrastItem> collect = itemList.stream()
            .collect(Collectors.groupingBy(
                    ContrastItem::getRange,
                    Collectors.summingLong(ContrastItem::getContrast)))
            .entrySet().stream()
            .map(entry -> new ContrastItem(entry.getKey(), entry.getValue()))
            .collect(Collectors.toList());
    System.out.println(collect);
}
英文:
Your approach is quite close,
itemList.stream()
        .collect(Collectors.groupingBy
        (
            ContrastItem::getRange,
            Collectors.summingLong(ContrastItem::getContrast)
        ));
this code creates a map {01:00:00-01:59:59=0, 00:00:00-00:59:59=4}
then you need to convert to ContrastItem list
public static void main(String[] args) {
    List<ContrastItem> itemList = new ArrayList<>();
    itemList.add(new ContrastItem("00:00:00-00:59:59", 3L));
    itemList.add(new ContrastItem("00:00:00-00:59:59", 1L));
    itemList.add(new ContrastItem("01:00:00-01:59:59", 0L));
    itemList.add(new ContrastItem("01:00:00-01:59:59", 0L));
    List<ContrastItem> collect = itemList.stream()
            .collect(Collectors.groupingBy(
                    ContrastItem::getRange,
                    Collectors.summingLong(ContrastItem::getContrast)))
            .entrySet().stream()
            .map(entry -> new ContrastItem(entry.getKey(), entry.getValue()))
            .collect(Collectors.toList());
    System.out.println(collect);
}
答案2
得分: 0
你绝对可以使用Stream来实现,看起来并不是很复杂。groupingBy + reducing是你需要的。
Collection<ContrastItem> items = contrastItems.stream()
   .collect(Collectors.groupingBy(
      ContrastItem::getRange,
      Collectors.reducing(new ContrastItem(0L, ""),
         (one, two) -> new ContrastItem(one.getContrast() + two.getContrast(),
                                        two.getRange()))))
   .values();
英文:
You can definitely do it with Stream and it looks not very complicated. groupingBy + reducing is what you need.
Collection<ContrastItem> items = contrastItems.stream()
   .collect(Collectors.groupingBy(
      ContrastItem::getRange,
      Collectors.reducing(new ContrastItem(0L, ""),
         (one, two) -> new ContrastItem(one.getContrast() + two.getContrast(),
                                        two.getRange()))))
   .values();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论