With lambdas, method references here, and the comparing methods of Comparator, one can write:
Arrays.sort(listOfFiles, Comparator.comparing(File::getName));
Arrays.sort(listOfFiles, Comparator.comparingLong(File::lastModified));
Arrays.sort(listOfFiles, Comparator.comparingLong(File::length));
This even allows composition of comparators, like reverse order, or first by last modified, then length or such.
Arrays.sort(listOfFiles, Comparator.comparingLong(File::length).reversed());
Arrays.sort(listOfFiles, Comparator.comparingLong(File::lastModified)
.thenComparingLong(File::length));
For an internal usage this suffices. For an external library API maybe not.
Sorting by file extension:
static final Comparator<File> BY_EXTENSION =
Comparator.comparing(f -> f.getName().replaceFirst("^(.*?)((\\.[^\\.]*)?)$", "$2"));
Arrays.sort(listOfFiles, BY_EXTENSION);
The lambda passed to sort does not need to be a method reference like File::getName
but can be some function on File.
The replaceFirst
should only keep the extension, yielding ".txt"
or ""
(no dot in name).
Or if you need the file extension as function:
class Foo { // Need some class name.
public static String getFileExtension(File file) {
return file.getName()
.replaceFirst("^(.*?)((\\.[^\\.]*)?)$", "$2");
}
}
Arrays.sort(Foo::getFileExtension);
Again using a method reference, though of a static method, File as parameter instead of as this
.
Should one use a Comparator<Path>
instead of Comparator<File>
- as Path is more general than File -, then be aware that Path.getName()
returns a Path
:
static final Comparator<Path> BY_EXTENSION =
Comparator.comparing(p -> p.getName().toString()
.replaceFirst("^(.*?)((\\.[^\\.]*)?)$", "$2"));
In one method:
public static final Comparator<Path> BY_NAME =
Comparator.comparing(File::getName);
public static final Comparator<Path> BY_MODIFIED =
Comparator.comparingLong(File::lastModified);
public static final Comparator<Path> BY_LENGTH =
Comparator.comparingLong(File::length);
public static final Comparator<Path> BY_EXTENSION =
Comparator.comparing(p -> p.getName().toString()
.replaceFirst("^(.*?)((\\.[^\\.]*)?)$", "$2"));
Either
Arrays.sort(listOfFiles, BY_NAME);
or:
void sortFiles(File[] files, Comparator<File> comparator) {
Arrays.sort(files, comparator);
}
sortFiles(listOfFiles, BY_NAME);
With Stream:
List<File> sortFiles(Stream<File> fileStream, Comparator<File> comparator) {
return fileStream.sorted(comparator).collect(Collectors.toList());
}
File[] fileArray = ...
List<File> fileList = ...
List<File> sorted = sorted(Arrays.stream(fileArray), BY_NAME);
List<File> sorted = sorted(fileList.stream(), BY_NAME);