Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 streams and maps worth it?

It feels like java 8 streams and mapping functions are so verbose they aren't really an improvement. For example, I wrote some code that uses a collection to generate another, modified collection:

private List<DartField> getDartFields(Class<?> model) {     List<DartField> fields = new ArrayList<>();     for (Field field : model.getDeclaredFields()) {         if (!Modifier.isStatic(field.getModifiers())) {             fields.add(DartField.getDartField(field));         }     }     return fields; } 

This seems like the ideal use case for java 8 streams and their functions, so I rewrote it like that:

private List<DartField> getDartFields(Class<?> model) {     return Arrays.asList(model.getDeclaredFields())             .stream()             .filter(field -> !Modifier.isStatic(field.getModifiers()))             .map(field -> DartField.getDartField(field))             .collect(Collectors.toList()); } 

But I'm not sure I like that more. It's 236 characters as compared to 239 in normal-style java. It doesn't seem more or less readable. It's nice that you don't have to declare an ArrayList, but needing to call .collect(Collectors.toList()) and Arrays.asList (depending on the data type) isn't any better.

Is there some practical improvement to using .stream() like this that I just don't get, or is this just a fun way to throw any coworkers for a loop who don't know functional programming?

I suppose if I were dynamically passing around filter or map lambdas it would be useful, but if you don't need to do that ...

like image 352
CorayThan Avatar asked Feb 02 '15 09:02

CorayThan


People also ask

Does Java 8 stream improve performance?

Until we realized just how much performance can suffer from overusing them. To be clear, streams introduced in Java 8 were slow and the comparison from the title started to arise in many forms. Still the advantages were clear and once Java 11 came, streams were greatly optimized.

Are Java 8 streams lazy?

The Java 8 Streams API is fully based on the 'process only on demand' strategy and hence supports laziness. In the Java 8 Streams API, the intermediate operations are lazy and their internal processing model is optimised to make it being capable of processing the large amount of data with high performance.

What are the advantages of Java 8 streams?

There are a lot of benefits to using streams in Java, such as the ability to write functions at a more abstract level which can reduce code bugs, compact functions into fewer and more readable lines of code, and the ease they offer for parallelization.


1 Answers

The problem is that you are not using the Stream API consistently. You are restricting the use case to something which can be best described as “actually not using the Stream API” as you are insisting on returning a Collection. That’s especially absurd as it’s a private method so you are entirely able to adapt the callers as well.

Consider to change the method to

private Stream<DartField> getDartFields(Class<?> model) {     return Stream.of(model.getDeclaredFields())             .filter(field -> !Modifier.isStatic(field.getModifiers()))             .map(field -> DartField.getDartField(field)); } 

and look what the caller(s) actually want to do. Usually they don’t need a Collection as an end in itself, but want to perform an action or even more operations which could be chained, e.g. print them:

getDartFields(Foo.class).forEach(System.out::println); 

The most interesting feature is the lazy nature of the stream, which implies that upon getDartFields return, no action has been performed yet and if you use operations like findFirst, there is no need to process all elements. You’ll lose this feature if you return a Collection containing all elements.

This also applies to multi-step processing where processing ordinary lists implies that for each step a new list has to be created and populated with results.

like image 60
Holger Avatar answered Sep 19 '22 06:09

Holger