Which of the following is better practice in Java 8?
Java 8:
joins.forEach(join -> mIrc.join(mSession, join));
Java 7:
for (String join : joins) {
mIrc.join(mSession, join);
}
I have lots of for loops that could be "simplified" with lambdas, but is there really any advantage of using them? Would it improve their performance and readability?
EDIT
I'll also extend this question to longer methods. I know that you can't return or break the parent function from a lambda and this should also be taken into consideration when comparing them, but is there anything else to be considered?
TL;DR:
List.stream().forEach()
was the fastest.I felt I should add my results from benchmarking iteration. I took a very simple approach (no benchmarking frameworks) and benchmarked 5 different methods:
for
List.forEach()
List.stream().forEach()
List.parallelStream().forEach
the testing procedure and parameters
The list in this class shall be iterated over and have some
doIt(Integer i)
applied to all it's members, each time via a different method. in the Main class I run the tested method three times to warm up the JVM. I then run the test method 1000 times summing the time it takes for each iteration method (usingSystem.nanoTime()
). After that's done i divide that sum by 1000 and that's the result, average time. example:I ran this on a i5 4 core CPU, with java version 1.8.0_05
classic
for
execution time: 4.21 ms
classic foreach
execution time: 5.95 ms
List.forEach()
execution time: 3.11 ms
List.stream().forEach()
execution time: 2.79 ms
List.parallelStream().forEach
execution time: 3.6 ms
I feel that I need to extend my comment a bit...
About paradigm\style
That's probably the most notable aspect. FP became popular due to what you can get avoiding side-effects. I won't delve deep into what pros\cons you can get from this, since this is not related to the question.
However, I will say that the iteration using Iterable.forEach is inspired by FP and rather result of bringing more FP to Java (ironically, I'd say that there is no much use for forEach in pure FP, since it does nothing except introducing side-effects).
In the end I would say that it is rather a matter of taste\style\paradigm you are currently writing in.
About parallelism.
From performance point of view there is no promised notable benefits from using Iterable.forEach over foreach(...).
According to official docs on Iterable.forEach :
... i.e. docs pretty much clear that there will be no implicit parallelism. Adding one would be LSP violation.
Now, there are "parallell collections" that are promised in Java 8, but to work with those you need to me more explicit and put some extra care to use them (see mschenk74's answer for example).
BTW: in this case Stream.forEach will be used, and it doesn't guarantee that actual work will be done in parallell (depends on underlying collection).
UPDATE: might be not that obvious and a little stretched at a glance but there is another facet of style and readability perspective.
First of all - plain old forloops are plain and old. Everybody already knows them.
Second, and more important - you probably want to use Iterable.forEach only with one-liner lambdas. If "body" gets heavier - they tend to be not-that readable. You have 2 options from here - use inner classes (yuck) or use plain old forloop. People often gets annoyed when they see the same things (iteratins over collections) being done various vays/styles in the same codebase, and this seems to be the case.
Again, this might or might not be an issue. Depends on people working on code.