如果可以同时修改或更新您正在排序的文件,请执行以下操作:
Java 8+
private static List<Path> listFilesOldestFirst(final String directoryPath) throws IOException {
try (final Stream<Path> fileStream = Files.list(Paths.get(directoryPath))) {
return fileStream
.map(Path::toFile)
.collect(Collectors.toMap(Function.identity(), File::lastModified))
.entrySet()
.stream()
.sorted(Map.Entry.comparingByValue())
// .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) // replace the previous line with this line if you would prefer files listed newest first
.map(Map.Entry::getKey)
.map(File::toPath) // remove this line if you would rather work with a List<File> instead of List<Path>
.collect(Collectors.toList());
}
}
Java 7
private static List<File> listFilesOldestFirst(final String directoryPath) throws IOException {
final List<File> files = Arrays.asList(new File(directoryPath).listFiles());
final Map<File, Long> constantLastModifiedTimes = new HashMap<File,Long>();
for (final File f : files) {
constantLastModifiedTimes.put(f, f.lastModified());
}
Collections.sort(files, new Comparator<File>() {
@Override
public int compare(final File f1, final File f2) {
return constantLastModifiedTimes.get(f1).compareTo(constantLastModifiedTimes.get(f2));
}
});
return files;
}
这两种解决方案都创建了一个临时的地图数据结构,以节省目录中每个文件的最后修改时间。我们需要这样做的原因是,如果在执行排序时更新或修改文件,则比较器将违反比较器接口的一般合同的可传递性要求,因为在修改过程中最后修改的时间可能会更改。
另一方面,如果您知道文件在排序过程中不会被更新或修改,那么您可以避免提交给该问题的几乎所有其他答案,我主要是:
Java 8+(排序期间无并发修改)
private static List<Path> listFilesOldestFirst(final String directoryPath) throws IOException {
try (final Stream<Path> fileStream = Files.list(Paths.get(directoryPath))) {
return fileStream
.map(Path::toFile)
.sorted(Comparator.comparing(File::lastModified))
.map(File::toPath) // remove this line if you would rather work with a List<File> instead of List<Path>
.collect(Collectors.toList());
}
}
注意:我知道您可以通过在排序流操作中使用Files :: getLastModifiedTime api 来避免上例中与File对象之间的转换,但是,那么您需要在lambda内部处理已检查的IO异常,这总是很麻烦的。我想说的是,如果性能足够关键,以至于转换是不可接受的,那么我要么将lambda中的已检查IOException传播为UncheckedIOException来进行处理,要么我完全放弃Files api而仅处理File对象:
final List<File> sorted = Arrays.asList(new File(directoryPathString).listFiles());
sorted.sort(Comparator.comparing(File::lastModified));