Case
saya ingin menggroup id yang sama dari list ini dan ingin sum dari parameter ke-3 dan nge avg parameter ke-4.
new Foo(1, "P1", 300.0, 400.0), new Foo(2, "P2", 600.0, 400.0), new Foo(3, "P3", 30.0, 20.0), new Foo(3, "P3", 70.0, 20.0), new Foo(1, "P1", 360.0, 40.0), new Foo(4, "P4", 320.0, 200.0), new Foo(4, "P4", 500.0, 900.0)
expectednya ketika di group akan seperti ini
new Foo(1, "P1", 660.0, 220.0), new Foo(2, "P2", 600.0, 400.0), new Foo(3, "P3", 100.0, 20.0), new Foo(4, "P4", 820.0, 550.0)
How To
buat class Foo
class Foo{ private int id; private String name; private double a; private double b; public Foo(int id, String name, double a, double b) { this.id = id; this.name = name; this.a = a; this.b = b; } @Override public String toString() { return "Foo{" + "id=" + id + ", name='" + name + '\'' + ", a=" + a + ", b=" + b + '}'; } }
buat data listnya
List<Foo> list = Arrays.asList( new Foo(1, "P1", 300, 400), new Foo(2, "P2", 600, 400), new Foo(3, "P3", 30, 20), new Foo(3, "P3", 70, 20), new Foo(1, "P1", 360, 40), new Foo(4, "P4", 320, 200), new Foo(4, "P4", 500, 900));
cara grouping perfield
list.stream().collect(Collectors.groupingBy(foo -> foo.id)) .entrySet() .stream() .forEach(e -> System.out.println(e));
listnya akan digrouping per idnya, idnya akan jadi key lalu valuenya berisi list of Foo yang idnya sama. jika dirun hasilnya akan seperti ini.
1=[Foo{id=1, name='P1', a=300, b=400.0}, Foo{id=1, name='P1', a=360, b=40.0}] 2=[Foo{id=2, name='P2', a=600, b=400.0}] 3=[Foo{id=3, name='P3', a=30, b=20.0}, Foo{id=3, name='P3', a=70, b=20.0}] 4=[Foo{id=4, name='P4', a=320, b=200.0}, Foo{id=4, name='P4', a=500, b=900.0}]
cara grouping per field dengan aggregation sum dan avg
list.stream().collect(Collectors.groupingBy(foo -> foo.id)) .entrySet() .stream() .map(e -> { double a = e.getValue().stream().mapToDouble(ax -> ax.a).sum(); double b = e.getValue().stream().mapToDouble(ax -> ax.b).average().getAsDouble(); return new Foo(e.getKey(), e.getValue().get(0).name, a, b); }) .forEach(foo -> { System.out.println(foo); });
kita sum field a dan avg field b lalu modife value dari Foo. jika dirun hasilnya akan seperti ini:
Foo{id=1, name='P1', a=660, b=220.0} Foo{id=2, name='P2', a=600, b=400.0} Foo{id=3, name='P3', a=100, b=20.0} Foo{id=4, name='P4', a=820, b=550.0}
berikut source lengkapnya:
package com.example.percobaan; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; public class Main { public static void main(String[] args) { List<Foo> list = Arrays.asList( new Foo(1, "P1", 300, 400), new Foo(2, "P2", 600, 400), new Foo(3, "P3", 30, 20), new Foo(3, "P3", 70, 20), new Foo(1, "P1", 360, 40), new Foo(4, "P4", 320, 200), new Foo(4, "P4", 500, 900)); list.stream().collect(Collectors.groupingBy(foo -> foo.id)) .entrySet() .stream() .forEach(e -> System.out.println(e)); System.out.println("\n==============\n"); list.stream().collect(Collectors.groupingBy(foo -> foo.id)) .entrySet() .stream() .map(e -> { double a = e.getValue().stream().mapToDouble(ax -> ax.a).sum(); double b = e.getValue().stream().mapToDouble(ax -> ax.b).average().getAsDouble(); return new Foo(e.getKey(), e.getValue().get(0).name, a, b); }) .forEach(foo -> { System.out.println(foo); }); } static class Foo{ private int id; private String name; private double a; private double b; public Foo(int id, String name, double a, double b) { this.id = id; this.name = name; this.a = a; this.b = b; } @Override public String toString() { return "Foo{" + "id=" + id + ", name='" + name + '\'' + ", a=" + a + ", b=" + b + '}'; } } }
Source: https://stackoverflow.com/questions/26340688/group-by-and-sum-objects-like-in-sql-with-java-lambdas
Komentar
Posting Komentar