簡體   English   中英

Java Stream GroupBy 和 SummingInt

[英]Java Stream GroupBy and SummingInt

我有一個 class foo 的列表

class foo(){
  private String location;
  private int total;

  //constructor, getters, and setters
}

我想根據它們的位置對 foo 列表進行分組並求和,如何使用 Java Streams 來實現它?

expected output
[
  {
    "location" = "locationA",
    "total" = 123
  },
  {
    "location" = "locationB",
    "total" = 167
  }
]

我所取得的成就:

{locationA=123, locationB=167}

我的代碼:

static Function<List<Case>, Object> totalPerYear = cases -> cases.stream()
                                                   .collect(Collectors.groupingBy((Case c)->c.getYear(), 
                                                   Collectors.summingInt((Case c)->c.getNumber())));

如果我正確理解了您的要求,您希望找到屬性值的total ,即每個location的總和。 如果是,您可以按以下方式進行:

Map<String, Integer> map = 
    list.stream()
    .collect(Collectors.groupingBy(Foo::getLocation, Collectors.summingInt(Foo::getTotal)));

演示:

public class Main {
    public static void main(String[] args) {
        List<Foo> list = List.of(new Foo("x", 10), new Foo("y", 5), new Foo("x", 15), new Foo("y", 10),
                new Foo("z", 10), new Foo("a", 10));

        Map<String, Integer> map = 
                list.stream()
                .collect(Collectors.groupingBy(Foo::getLocation, Collectors.summingInt(Foo::getTotal)));

        System.out.println(map);
    }
}

Output:

{a=10, x=25, y=15, z=10}

我假設您有一個 object 的列表,該列表具有通用名稱和可變總價,並且您希望添加與該命令名稱相對應的總計並顯示 output 和相同的結構。 這是我嘗試這樣做的方法:

package com.example;

import com.google.gson.Gson;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

class LocationData {
    String name;
    int total;

    public LocationData(String name, int total) {
        this.name = name;
        this.total = total;
    }

    public enum LocationNames {
        LocationA,
        LocationB,
        LocationC,
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getTotal() {
        return total;
    }

    public void setTotal(int total) {
        this.total = total;
    }
}

public class SampleStreamGroupBy {
    public static void main(String[] args) {
        List<LocationData> input = new ArrayList<>();
        input.add(new LocationData(LocationData.LocationNames.LocationA.name(), 1));
        input.add(new LocationData(LocationData.LocationNames.LocationA.name(), 2));
        input.add(new LocationData(LocationData.LocationNames.LocationA.name(), 3));
        input.add(new LocationData(LocationData.LocationNames.LocationB.name(), 4));
        input.add(new LocationData(LocationData.LocationNames.LocationB.name(), 100));
        input.add(new LocationData(LocationData.LocationNames.LocationC.name(), 5));

        Map<String, Integer> collect = input.stream()
                .collect(Collectors.groupingBy(LocationData::getName, Collectors.summingInt(LocationData::getTotal)));
        System.out.println(collect);

        List<LocationData> locationDataList = collect.entrySet().stream()
                .map(entry -> new LocationData(entry.getKey(), entry.getValue()))
                .collect(Collectors.toList());
        System.out.println(new Gson().toJson(locationDataList));
    }
}

應該打印類似的東西

{LocationC=5, LocationA=6, LocationB=104}
[{"name":"LocationC","total":5},{"name":"LocationA","total":6},{"name":"LocationB","total":104}]

我假設您想要 map 案例列表到 foos 列表:

class Main {

    private static List<Integer> costsList;

    public static void main(String args[]) throws Exception {
        List<Case> list = new ArrayList<>();
        list.add(new Case("2020", 4));
        list.add(new Case("2021", 2));
        list.add(new Case("2020", 2));
        list.add(new Case("2022", 3));
        List<Foo> foos = totalPerYear.apply(list);
        foos.forEach(System.out::println);

    }


    static Function<List<Case>, List<Foo>> totalPerYear = cases -> cases.stream()
            .collect(Collectors.groupingBy(Case::getYear, Collectors.summingInt(Case::getNumber)))
            .entrySet()
            .stream()
            .map(entry -> new Foo(entry.getKey(), entry.getValue()))
            .collect(Collectors.toList());


    static class Foo {
        private String year;
        private int total;

        public Foo(String year, int total) {
            this.year = year;
            this.total = total;
        }

        public String getYear() {
            return year;
        }

        public void setYear(String year) {
            this.year = year;
        }

        public int getTotal() {
            return total;
        }

        public void setTotal(int total) {
            this.total = total;
        }

        @Override
        public String toString() {
            return "Foo{" +
                    "year='" + year + '\'' +
                    ", total=" + total +
                    '}';
        }
    }

    static class Case {
        private String year;
        private int number;

        public Case(String year, int number) {
            this.year = year;
            this.number = number;
        }

        public String getYear() {
            return year;
        }

        public void setYear(String year) {
            this.year = year;
        }

        public int getNumber() {
            return number;
        }

        public void setNumber(int number) {
            this.number = number;
        }
    }
}

Output:

Foo{year='2022', total=3} 
Foo{year='2021', total=2} 
Foo{year='2020', total=6}
    var data = List.of(
        new Foo("A", 17),
        new Foo("B", 30),
        new Foo("Y", 68),
        new Foo("A", 30),
        new Foo("B", 25),
        new Foo("Y", 51),
        new Foo("Z", 1)
    );

    var result = data.stream()
        .collect(Collectors.groupingBy(Foo::getLocation, Collectors.summingInt(Foo::getTotal)));

output:

result = {A=47, B=55, Y=119, Z=1} 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM