Although you can use the List.sort(Comparator) method, the main purpose of this method is overridden. Prior to Java-8, sorting each List was somewhat inefficient. First, the list was dumped into the array using the toArray() method, then the array was sorted, and finally, the list was updated through ListIterator.set . In Java-8, this is the default behavior implemented in the default List.sort(Comparator) method. However, you can change it in subclasses if you can provide a more efficient algorithm. Examples:
ArrayList and Arrays.asList() provide their own implementation of sort , which directly sorts the internal array, so you do not need to copy back and forth.
CopyOnWriteArrayList can be sorted right now! Try the following code:
List<String> list = new CopyOnWriteArrayList<>(Arrays.asList("a", "c", "b")); Collections.sort(list);
In Java-7, it throws an UnsupportedOperationException , because ListIterator.set support contradicts the idea of ββthis list (each iterator ListIterator.set through an independent snapshot). In Java-8, ListIterator.set is still not supported, but this code is working correctly due to a custom sorting implementation.
Collections.singletonList and Collections.emptyList just do nothing (sorting 0 or 1 elements is non-op), which is certainly faster than creating an array with one element or zero element, sorting and iterating over the list to set the value back.
Collections.unmodifiableList now just throws an UnsupportedOperationException . Before Java-8, you received an exception only after you dropped an immutable list into an array, sorted the array, and started writing it.
Here is an example that may be useful in user code. Suppose you want to create a mapped view of some list:
public class MappedList<T, R> extends AbstractList<R> { private final List<T> source; private final Function<? super T, ? extends R> mapper; public MappedList(List<T> source, Function<? super T, ? extends R> mapper) { this.source = source; this.mapper = mapper; } @Override public R get(int index) { return mapper.apply(source.get(index)); } @Override public int size() { return source.size(); } }
Usage example:
List<String> list = Arrays.asList("a", "foo", "bb", "bar", "qq"); List<Integer> mappedList = new MappedList<>(list, String::length); System.out.println(mappedList);
Works great, but when trying Collections.sort(mappedList); you will get an UnsupportedOperationException (the set operation does not work, since you cannot cancel the mapping function). However, if you implement the sort() method in a MappedList , you can sort it correctly (change the original list):
@Override public void sort(Comparator<? super R> c) { @SuppressWarnings("unchecked") Comparator<? super T> comparator = c == null ? Comparator.comparing((Function<? super T, ? extends Comparable<Object>>) mapper) : Comparator.comparing(mapper, c); source.sort(comparator); } List<String> list = Arrays.asList("a", "foo", "bb", "bar", "qq"); List<Integer> mappedList = new MappedList<>(list, String::length); Collections.sort(mappedList); System.out.println(mappedList);