Reputation: 1176
How stream search, based on previous filter results, can be simplified ?
HashMap<Boolean, List<Path>> result = (HashMap<Boolean, List<Path>>) Files.walk(Paths.get(folder)).map(Path
::toAbsolutePath).collect(Collectors.groupingBy(Files::isSymbolicLink));
result.get(true).stream().filter(path -> {
try {
return !result.get(false).contains(Files.readSymbolicLink(path));
} catch (IOException e) {
throw Throwables.propagate(e);
}
}).forEach(symbolicLink -> {
try {
result.get(false).addAll(Files.walk(symbolicLink, FileVisitOption.FOLLOW_LINKS).collect(Collectors
.toList()));
} catch (IOException e) {
throw Throwables.propagate(e);
}
});
return result.get(false).stream().filter(Files::isRegularFile).distinct().collect(Collectors.toList());
Upvotes: 0
Views: 69
Reputation: 2759
You could tidy it up by extracting some of the code into methods, and by avoiding using a HashMap
.
Instead of a HashMap
you can store the files in a Set<Path>
. This enforces uniqueness, so you don't really need to bother checking if the symbolic link leads to a file you already have, and you can remove some of the filtering:
public Set<Path> getAllFiles(final String folder) throws IOException {
return Files.walk(Paths.get(folder))
.map(Path::toAbsolutePath)
.flatMap(this::getAllFiles)
.collect(Collectors.toSet());
}
private Stream<Path> getAllFiles(final Path path) {
if(!Files.isSymbolicLink(path)) return Stream.of(path);
try {
return Files.walk(path, FileVisitOption.FOLLOW_LINKS)
.filter(Files::isRegularFile);
} catch (IOException e) {
e.printStackTrace();
}
return Stream.empty();
}
Upvotes: 1