如何根据以前的过滤结果简化流搜索?(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());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());最满意答案
您可以通过将一些代码提取到方法中并避免使用HashMap来整理它。
您可以将文件存储在Set<Path>而不是HashMap 。 这样可以强制执行唯一性,因此您不必费心检查符号链接是否指向您已有的文件,并且可以删除一些过滤:
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(); }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(); }更多推荐
发布评论