Using Java 8 List.sort

The List class in Java 8 adds a new sort method to it. Can someone clarify when I should use this and not the Collections.sort(..) method?

+5
source share
5 answers

There is no functional difference because Collections.sort(list) calls list.sort(null) and Collections.sort(list, comparator) calls list.sort(comparator) .

So, it’s just a matter of style - when you provide your own comparator, calling sort on a list is probably more natural and readable than using an external static method.

However, if you just want to sort the list in natural order, Collections.sort(list) might be more understandable than list.sort(null) .

+4
source

You have to go List.sort .

An example of using List.sort to sort the String list by the length of the elements:

 List<String> list = new ArrayList<>(Arrays.asList("aa", "aaa", "a")); list.sort(comparing(String::length)); 

Collections.sort() was the pre-Java 8 way of this. Please note that there is no real difference between the two. If you look at the Collections.sort source code, you may notice that it calls List.sort :

 public static <T extends Comparable<? super T>> void sort(List<T> list, Comparator<? super T> c) { list.sort(c); } 
+3
source

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); // prints [1, 3, 2, 3, 2] 

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); // prints [1, 2, 2, 3, 3] System.out.println(list); // prints [a, bb, qq, foo, bar] 
+3
source

You should use it by providing your own comparator. For instance:

 list.sort(Comparator.reverseOrder()); 

Instead:

 Collections.sort(list); Collections.reverse(list); 
0
source

List the class as part of the JSR 335 changes, and we can use this method to sort the list:

// Use the sort method in the list.

personList.sort ((p1, p2) β†’ p1.firstName.compareTo (p2.firstName));

- before java 8 we can use this tye only --- Collections.sort (personList, (p1, p2) β†’ p1.firstName.compareTo (p2.firstName));

0
source

Source: https://habr.com/ru/post/1232618/


All Articles