Joey
Joey

Reputation: 121

Java 8 Stream - aggregate and return aggregation steps

I am new to java 8 stream api and I am seeking for a solution to run through my list of objects and aggretate certain property to be able in the end to get a new list of that property type and all the aggreation results.

for example my list has 10 person objects inside and i want a list of all the age differences based on first persons age

is that even in java possible with stream?

for example:

person1.age = 10
person2.age = 12
person3.age = 20
person4.age = 25
person5.age = 30

after doing stream magic the results should of type int and be looking like this

0
2 //based on first age 12 - 10
10 // based on first age 20 - 10
15 // ...
20

Upvotes: 1

Views: 1050

Answers (3)

Jaroslaw Pawlak
Jaroslaw Pawlak

Reputation: 5578

I assume that you have a class called Person with a getAge() getter on it. Then you can do:

list.stream()
    .skip(1)
    .map(Person::getAge)
    .map(age -> age - list.get(0).getAge())
    .map(Math::abs)
    .forEach(System.out::println);

.skip(1) - skips the first person from the list so the result won't contain 0 produced by comparing first person's age to themselves.

.map(Math::abs) - takes the absolute value as "difference" is always positive (whether I have 10 years and you have 20, or I have 20 and you have 10, the difference is 10).

You might want to add .distinct() to remove duplications.

Finally, you might want to use different terminal operation - e.g. .collect(toList()), rather than printing.

Upvotes: 2

azro
azro

Reputation: 54148

I supposed you had a Person class, and I made my code on this supposition because you give anything.

public static void main(String [] args) {
    List<Person> list = new ArrayList<Person>();
    Person person1 = new Person();
    person1.age = 10;
    Person person2 = new Person();
    person2.age = 12;
    Person person3 = new Person();
    person3.age = 20;
    Person person4 = new Person();
    person4.age = 25;
    Person person5 = new Person();
    person5.age = 30;

    list.add(0,person1);
    list.add(person2);
    list.add(person3);
    list.add(person4);
    list.add(person5);

    list.stream().forEach(person -> System.out.println(person.age-list.get(0).age));
}

And here you have

If you want to put the values in a list :

List<Integer> list2 = new ArrayList<Integer>();
list.stream().forEach(person -> list2.add(person.age-list.get(0).age));

Because you write person.age=10 it appears you set the visibility of age as public, which is not very good, you need to set it as private and provide a getter for it :

public int getAge(){
    return this.age;
}

Upvotes: 0

CraigR8806
CraigR8806

Reputation: 1584

Assuming that the list is already sorted(if not you would need to sort by age). You could extract lst.get(0).getAge() and then do something like this:

List<Integer> diff = lst.stream().map((x)->x.getAge()-firstAge).collect(Collectors.toList());

I am not condoning naming any List lst. That is bad practice, but seeing as you did not share any code with us, I do not know what you named your list of people.

Upvotes: 1

Related Questions