experience trying out lambda-8-b74
Arne Siegel
v.a.ammodytes at googlemail.com
Sun Jan 27 05:31:54 PST 2013
Hi lambda nation,
was wondering if I could lambda-ize this little file system crawler:
public void forAllFilesDo(Block<File> fileConsumer, File baseFile) {
if (baseFile.isHidden()) {
// do nothing
} else if (baseFile.isFile()) {
fileConsumer.accept(baseFile);
} else if (baseFile.isDirectory()) {
File[] files = baseFile.listFiles();
Arrays.stream(files).forEach(f -> forAllFilesDo(fileConsumer, f));
}
}
Using b74, the following reformulation produces the identical behaviour:
public void forAllFilesDo3(Block<File> fileConsumer, File baseFile) {
BiBlock<Stream.Downstream<File>,File> fileExploder = (ds, f) -> {
if (f.isHidden()) {
// do nothing
} else if (f.isFile()) {
ds.send(f);
} else if (f.isDirectory()) {
Arrays.stream(f.listFiles())
.forEach(fi -> fileExploder(ds, fi)); /* recursive call ! */
}
};
Arrays.stream(new File[] {baseFile})
.explode(fileExploder)
.forEach(fileConsumer::accept);
}
As my next step I was looking if I could parallelize the last step. But simply inserting .parallel()
seems not to be working - presumably because the initial one-element Spliterator is
governing split behaviour.
Inserting .collect(Collectors.<File>toList()).parallelStream() instead works fine:
Arrays.stream(new File[] {baseFile})
.explode(fileExploder)
.collect(Collectors.<File>toList())
.parallelStream()
.forEach(fileConsumer::accept);
Main observations:
(*) Exploding a single element requires a lot of programming overhead:
1st step - creation of a one-element array or collection
2nd step - stream the result of the 1st step
3rd step - explode the result of the 2nd step
Not sure if anything can be done about this.
(*) .parallel() after .explode() behaves unexpectedly. Maybe the downstream should be based
on a completely fresh unknown-size spliterator.
Regards
Arne Siegel
More information about the lambda-dev
mailing list