並べ替えを実行しているときに、並べ替え中のファイルを変更または更新できる場合:
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オブジェクトとの間の変換を回避できることを知っていますが、ラムダ内のチェックされたIO例外を処理する必要があり、これは常に困難です。パフォーマンスが非常に重要であり、変換が受け入れられない場合は、ラムダ内のチェックされたIOExceptionをUncheckedIOExceptionとして伝達するか、Files APIを完全に無視してFileオブジェクトのみを処理します。
final List<File> sorted = Arrays.asList(new File(directoryPathString).listFiles());
sorted.sort(Comparator.comparing(File::lastModified));