如果您正在排序的文件可以在执行排序的同时进行修改或更新:
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 来避免上述示例中的文件对象之间的转换,但是,您需要在 lambda 中处理已检查的 IO 异常,这总是一种痛苦。我会说如果性能足够关键以至于翻译是不可接受的,那么我要么通过将其作为 UncheckedIOException 传播来处理 lambda 中的已检查 IOException,要么我完全放弃 Files api 并仅处理 File 对象:
final List<File> sorted = Arrays.asList(new File(directoryPathString).listFiles());
sorted.sort(Comparator.comparing(File::lastModified));