หากไฟล์ที่คุณเรียงลำดับสามารถแก้ไขหรืออัพเดตได้ในเวลาเดียวกันการเรียงลำดับจะถูกดำเนินการ:
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;
}
โซลูชันทั้งสองนี้สร้างโครงสร้างข้อมูลแผนที่ชั่วคราวเพื่อประหยัดเวลาแก้ไขล่าสุดสำหรับแต่ละไฟล์ในไดเรกทอรี เหตุผลที่เราต้องทำคือถ้าไฟล์ของคุณมีการปรับปรุงหรือแก้ไขในขณะที่การเรียงลำดับของคุณกำลังดำเนินการแล้วตัวเปรียบเทียบของคุณจะละเมิดข้อกำหนดความไวของสัญญาทั่วไปของอินเทอร์เฟซของ Comparator เพราะเวลาที่แก้ไขล่าสุดอาจเปลี่ยนแปลงในระหว่างการเปรียบเทียบ
หากในอีกทางหนึ่งคุณรู้ว่าไฟล์จะไม่ได้รับการปรับปรุงหรือแก้ไขในระหว่างการเรียงลำดับคุณสามารถหนีไปพร้อมกับคำตอบอื่น ๆ ที่ส่งไปยังคำถามนี้ซึ่งเป็นส่วนหนึ่งของ:
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 ในการดำเนินการสตรีมที่เรียงลำดับอย่างไรก็ตามคุณต้องจัดการกับข้อยกเว้น IO ที่เลือกไว้ภายในแลมบ์ดาของคุณ . ฉันจะบอกว่าถ้าประสิทธิภาพมีความสำคัญมากพอที่การแปลนั้นจะไม่เป็นที่ยอมรับฉันก็จะจัดการกับ IOException ที่ถูกตรวจสอบในแลมบ์ดาโดยการเผยแพร่มันเป็น UncheckedIOException หรือฉันต้องการนำไฟล์ API ทั้งหมดมารวมกัน
final List<File> sorted = Arrays.asList(new File(directoryPathString).listFiles());
sorted.sort(Comparator.comparing(File::lastModified));