I have this stream, as well as quite a few others, where I abuse a bunch of calls to get the job done. Seems like an anti-pattern when taking advantage of J8.
+ Arrays.stream(resources)
+ .map(this::ingestFromFile)
+ .collect(Collectors.toList())
+ .stream()
+ .map(Container.class::cast)
+ .map(Container::getAll)
+ .flatMap(Collection::stream)
+ .collect(Collectors.toList())
+ .forEach(
+ dataType -> {
+ loaderConstants.getRepo(dataType.toString()).save(dataType);
+ LOGGER.log(Level.INFO, "Saved: " + dataType);
+ });
How can I shorten this up and what pitfalls should I look out for in the future to avoid this type of development?
Well, you don't need the intermediate .collect(Collectors.toList())
calls as it's unnecessary and causes avoidable overhead.
Arrays.stream(resources)
.map(this::ingestFromFile)
.map(Container.class::cast)
.map(Container::getAll)
.flatMap(Collection::stream)
.forEach(
dataType -> {
loaderConstants.getRepo(dataType.toString()).save(dataType);
LOGGER.log(Level.INFO, "Saved: " + dataType);
});
Then you can extract the body of the forEach
to a method to simplify the pipeline.
My name is Andy, and I don't like streams.
And this code is a great example of why. (OK, they are sometimes helpful; but really only in very simple cases).
One thing that you (hopefully) learn very early on in programming is that identation makes your code readable: it helps you understand where things happen on related values.
In streamy code, indentation goes right out of the window. That left-hand margin is straight - see how all the periods line up:
+ Arrays.stream(resources)
+ .map(this::ingestFromFile)
+ .collect(Collectors.toList())
+ .stream()
+ .map(Container.class::cast)
+ .map(Container::getAll)
+ .flatMap(Collection::stream)
+ .collect(Collectors.toList())
+ .forEach(
+ dataType -> {
+ loaderConstants.getRepo(dataType.toString()).save(dataType);
+ LOGGER.log(Level.INFO, "Saved: " + dataType);
+ });
There is just no visual structure to it.
Especially as this is using forEach
, it would just be easier to use loops.
for (var resource : resources) {
var fromFile = resource.ingestFromFile();
var container = (Container) fromFile;
for (var dataType : container.getAll()) {
loaderConstants.getRepo(dataType.toString()).save(dataType);
LOGGER.log(Level.INFO, "Saved: " + dataType);
}
}
(You may not be using Java 10; but I don't know the data types anyway. Fill in type types instead of var
if you need it).
Personally, I think that is way easier to read. And it's shorter.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.