![](/img/trans.png)
[英]java.util.stream.Collectors: Why is the summingInt implemented with an array?
[英]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.