On 29/04/2016 10:23, Andrej Golovnin wrote:
:
"There are many Java 8 developers using streams() and optionals
with an imperative programming mindset still."
And here is an example from JDK. Take look at the code
http://cr.openjdk.java.net/~smarks/reviews/8140281/webrev.0.jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java-.html
:
397 cf.modules().forEach(m -> {
398 ModuleReference mref = m.reference();
399 map.put(mref.descriptor().name(), mref);
400 });
401
402 // set of modules that are observable
403 Set<ModuleReference> mrefs = new HashSet<>(map.values());
404
405 // add the other modules
406 for (String mod : otherMods) {
407 Optional<ModuleReference> omref = finder.find(mod);
408 if (omref.isPresent()) {
409 ModuleReference mref = omref.get();
410 map.putIfAbsent(mod, mref);
411 mrefs.add(mref);
412 } else {
413 // no need to fail
414 }
415 }
It is a mix of imperative and functional programming.
But you can rewrite it in a more functional style.
The lines 397-400 can be rewritten as:
cf.modules()
.stream()
.map(ResolvedModule::reference)
.forEach(mref -> map.put(mref.descriptor().name(), mref));
which btw is exactly how it is implemented elsewhere. However it was not
possible to write it this way before refactoring of the API a few weeks
ago and it's just that the jlink code wasn't cleaned up much during the
refactoring.
In general then we have lots of code in the JDK that could be refactored
and cleaned up. Some of the new code (such as jlink) has had to go
through many iterations and refactoring and very easy to end up with
mixes of functional and imperative. I expect there will be a lot of
churn in this code over the coming months (not features work and just
improving and iterating on the current implementation) and hopefully in
better shape then.
-Alan.