I was playing around with Java8 lambda expressions. As an example I then tried to sum up the ages persons contained in a list:
import java.util.Arrays;
import java.util.List;
public class Person {
public static void main(String[] args) {
List<Person> persons = Arrays.asList(new Person("FooBar", 12), new Person("BarFoo", 16));
Integer sumOfAges = persons.stream().map(Person::getAge).sum();
System.out.println("summedUpAges: " + sumOfAges);
}
private final String name;
private final Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
}
When I try to compile this snippet with the following java compiler:
openjdk version "1.8.0-ea"
OpenJDK Runtime Environment (build 1.8.0-ea-lambda-night
OpenJDK 64-Bit Server VM (build 25.0-b21, mixed mode)
I get the following compile error:
java: cannot find symbol
symbol: method sum()
location: interface java.util.stream.Stream<java.lang.Integer>
But if I change the return value of the getAge() method from Integer to int, I get the expected result. But sometimes it is not possible or desired to change signatures on the fly. Is there any way to make this working when getAge() returns a Integer type?
Thanks in advance
Using Stream.collect() The second method for calculating the sum of a list of integers is by using the collect() terminal operation: List<Integer> integers = Arrays. asList(1, 2, 3, 4, 5); Integer sum = integers. stream() .
In order to match a lambda to a single method interface, also called a "functional interface", several conditions need to be met: The functional interface has to have exactly one unimplemented method, and that method (naturally) has to be abstract.
Operations and example of using Java 8 streamsjoining(“ ”)) utilizes functional programming style by applying Java 8 streams functions to perform an operation on the elements of a list by joining them with space “ “ between the words and this was an example of how streams are used.
I think they are changing the method
IntStream map(ToIntFunction<? super T> mapper)
to
IntStream mapToInt(ToIntFunction<? super T> mapper)
then your
persons.stream().mapToInt(Person::getAge).sum()
will always work, whether getAge()
returns int
or Integer
.
See this thread: http://mail.openjdk.java.net/pipermail/lambda-libs-spec-experts/2013-March/001480.html
BTW you can post your questions to lambda-dev mailing list, they'd like to hear real world experiences.
They are not changing the methods, both of them are available where as map() is a generalized method that returns Stream, and they have separated the int, long, double Stream into separate method such as mapToInt(), mapToLong() and mapToDouble().
Yes, you can use reduce() method
reduce(T identity, BinaryOperator< T > accumulator)
Performs a reduction on the elements of this stream, using an associative accumulation function, and returns an Optional describing the reduced value, if any.
How reduce() works: suppose we have stream of int array and we apply the reduce function
reduce(0, (l, r) -> l + r)
In a list of integers such as 1, 2, 3, 4, and 5, the seed 0 is added to 1 and the result (1) is stored as the accumulated value, which then serves as the left-hand value in addition to serving as the next number in the stream (1+2). The result (3) is stored as the accumulated value and used in the next addition (3+3). The result (6) is stored and used in the next addition (6+4), and the result is used in the final addition (10+5), yielding the final result 15.
So you example would look like:
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class Person {
public static void main(String[] args) {
List<Person> persons = Arrays.asList(new Person("FooBar", 12), new Person("BarFoo", 16));
Stream<Integer> stream = persons.stream().map(x -> x.getAge());
int sum = stream.reduce(0, (l, r) -> l + r);
System.out.println(sum);
}
private final String name;
private final Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public Integer getAge() {
return age;
}
}
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