Jika file yang Anda sortir dapat dimodifikasi atau diperbarui pada saat yang sama, sortir dilakukan:
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;
}
Kedua solusi ini membuat struktur data peta sementara untuk menghemat waktu modifikasi terakhir konstan untuk setiap file dalam direktori. Alasan kami perlu melakukan ini adalah bahwa jika file Anda sedang diperbarui atau dimodifikasi saat pengurutan Anda dilakukan maka komparator Anda akan melanggar persyaratan transitivitas dari kontrak umum antarmuka komparator karena waktu modifikasi terakhir dapat berubah selama perbandingan.
Jika, di sisi lain, Anda tahu file tidak akan diperbarui atau diubah selama pengurutan Anda, Anda bisa lolos dengan cukup banyak jawaban lain yang dikirimkan ke pertanyaan ini, yang sebagian saya:
Java 8+ (Tidak ada modifikasi bersamaan saat penyortiran)
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());
}
}
Catatan: Saya tahu Anda dapat menghindari terjemahan ke dan dari objek File dalam contoh di atas dengan menggunakan File :: getLastModifiedTime api dalam operasi aliran yang diurutkan, namun, maka Anda harus berurusan dengan pengecualian IO yang dicentang di dalam lambda Anda yang selalu menyusahkan. . Saya akan mengatakan jika kinerjanya cukup kritis sehingga terjemahannya tidak dapat diterima maka saya akan berurusan dengan IOException yang dicentang di lambda dengan menyebarkannya sebagai UncheckedIOException atau saya akan mengabaikan api File sama sekali dan hanya berurusan dengan objek File:
final List<File> sorted = Arrays.asList(new File(directoryPathString).listFiles());
sorted.sort(Comparator.comparing(File::lastModified));