How to sort List<File> to list directories first and grouping files by directory?

一世执手 提交于 2019-12-22 04:28:10

问题


In order to get all files contained in a specified directory and according to some extensions, I'm using the method listFiles of class FileUtils from Apache Commons IO library, as in the following code sample.

ArrayList<String> wildcards = new ArrayList<>();
wildcards.add("*.cpp");
wildcards.add("*.h");
wildcards.add("*.txt");

File dir = new File("/path/to/dir");
Collection<File> found = FileUtils.listFiles(
        dir,
        new WildcardFileFilter(wildcards, IOCase.SENSITIVE),
        DirectoryFileFilter.DIRECTORY);

List<File> files = new ArrayList<>(found);

The order of items in the resulting Collection<File> varies in the different operating systems, so I would sort them (ie. the wrapping list files) in according to the following rules.

  • The directories should be listed before the files.
  • The sorting routine should group files by directory.

Example:

/path/to/dir/first/subpath/main.cpp
/path/to/dir/first/subpath/utils.cpp
/path/to/dir/first/subpath/utils.h
/path/to/dir/first/main.cpp
/path/to/dir/first/utils.cpp
/path/to/dir/first/utils.h
/path/to/dir/second/main.cpp
/path/to/dir/second/utils.cpp
/path/to/dir/second/utils.h
/path/to/dir/README.txt

回答1:


You can use Java 8's streams to solve your problem. Something like this should work:

//untested
Map<Path, List<Path>> dirToFileMap = files.stream()
            .map(f -> Paths.get(f.getAbsolutePath()))
            .collect(Collectors.groupingBy(Path::getParent));

With that map you can achieve what you need. Iterate over keySet first, for example.




回答2:


Just a matter of typing; below I do not take canonical paths (Windows is case-insensitive), but the gist is clear.

So a Comparator for sorting:

public class FileComparator extends Comparator<File> {

    @Override
    public int compareTo(File lhs, File rhs) {
        if (lhs == null && rhs == null) {
            return 0;
        } else if (lhs == null || rhs == null) {
            return lhs == null ? -1 : 1;
        }
        int cmp = compareTo(lhs.getParentFile(), rhs.getParentFile());
        if (cmp == 0) {
            if (lhs.isDirectory() != rhs.isDirectory()) {
                return lhs.isDirectory() ? -1 : 1;
            }
            cmp = lhs.getName().compareTo(rhs.getName());
        }
        return cmp;
    }

    @Override
    public boolean equals(Object comparator) {
        return comparator != null && comparator.getClass().equals(getClass());
    }
}

As always the equals just compares comparators, not Files.



来源:https://stackoverflow.com/questions/32312738/how-to-sort-listfile-to-list-directories-first-and-grouping-files-by-directory

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!