I have a Java class:
class Person {
String firstName;
String lastName;
int income;
public Person(String firstName, String lastName, int income)
{
this.firstName = firstName;
this.lastName = lastName;
this.income = income;
}
I have a Collection<Person>, with 4 x Person objects:
Collection<Person> persons = new ArrayList<>();
persons.add(new Person("John", "Smith", 5));
persons.add(new Person("Mary", "Miller", 2));
persons.add(new Person("John", "Smith", 4));
persons.add(new Person("John", "Wilson", 4));
I want to make a new Collection instance, but from the elements with the same "firstName" and "lastName", make 1 element, and the result "income" will be the sum of the "incomes" of each element. So, for this particular case, the resulting collection will have 3 elements, and "John Smith" will have the "income" = 9.
In SQL, the equivalent query is:
SELECT FIRSTNAME, LASTNAME, SUM(INCOME) FROM PERSON GROUP BY FIRSTNAME, LASTNAME
I found only answers which contain Map as result, and "key" contains the column(s) used for grouping by. I want to obtain directly a similar type of collection from the initial (ArrayList<Person>), and not a Map, because if in my collection I have millions of elements, it will decrease the performance of the code. I know it was easier if I worked on SQL side, but in this case I must work on Java side.
I don't know if that is the most beautiful solution, but you can try to groupBy firstName and lastName with a delimiter between them, let's say .. After you collect your data into Map<String, Integer> that contains your firstName.lastName, you create new list of Person from it.
List<Person> collect = persons.stream()
.collect(Collectors.groupingBy(person -> person.getFirstName() + "." + person.getLastName(),
Collectors.summingInt(Person::getIncome)))
.entrySet().stream().map(entry -> new Person(entry.getKey().split(".")[0],
entry.getKey().split(".")[1],
entry.getValue()))
.collect(Collectors.toList());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With