Two static methods in the Collections class sorts List.
sort(List list)
sorts the elements in
a List
in the order defined by the Comparable
interface
that is implemented by the elements. sort(List list, Comparator c)
sorts the elements with
a Comparator
object passed in.
We can also use sort(Comparator c)
in the List interface
to sort a List without using the Collections
class.
The following code demonstrates how to sort a List
:
import java.util.ArrayList; import java.util.Collections; import java.util.List; //from w w w .j a va 2 s .c o m public class Main { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("J"); list.add("R"); list.add("C"); list.add("X"); System.out.println("List: " + list); // Uses Comparable implementation in String class // to sort the list in natural order Collections.sort(list); System.out.println("Sorted List: " + list); } }
The code above generates the following result.
The following code sorts the list in ascending order of
the length of their elements using the
sort()
method in the List interface:
import java.util.ArrayList; import java.util.Comparator; import java.util.List; /*from w ww . j a v a 2 s .c om*/ public class Main { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("Java"); list.add("R"); list.add("CSS"); list.add("XML"); System.out.println("List: " + list); // Uses List.sort() method with a Comparator list.sort(Comparator.comparing(String::length)); System.out.println("Sorted List: " + list); } }
The code above generates the following result.
The sort()
method uses a modified mergesort algorithm which
is a stable sort.
In a stable sort the equal elements will stay at their current positions after the sort operation.
Sorting gives n*log(n)
performance, where n
is the number of elements in the List.
Two static binarySearch()
method in the
Collections class search for a key in a List.
This method uses the binary search algorithm to perform the search.
int binarySearch(List list, T key) int binarySearch(List list, T key, Comparator c)
A List
must be sorted in ascending order before
we can use the binarySearch()
method.
If the key is found in the List, the method returns its index in the List.
If the key is not found in the list,
it returns (-(insertion_index) -1)
,
where the Math.abs((-(insertion_index) -1))
is the index where
we can insert this key still keep the list in order.
The return is a negative value when the key is not found in the List.
The following snippet of code shows how to use this method:
import java.util.ArrayList; import java.util.Collections; import java.util.List; /* w w w. j a v a 2 s.c o m*/ public class Main { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("Java"); list.add("R"); list.add("CSS"); list.add("XML"); Collections.sort(list); System.out.println("List: " + list); int index = Collections.binarySearch(list, "CSS"); System.out.println("CSS in List is at " + index); index = Collections.binarySearch(list, "Javascript"); System.out.println("Javascript in List is at " + index); } }
The code above generates the following result.
Since "Javascript" is not in the List, the binary search returned -3. It means that if you insert "Javascript" in the List, it will be inserted at index 2, which is computed using the expression (-(-2+1)).
Shuffling gives us a random permutation of the elements in a List.
The two versions of the shuffle() methods from Collections class are as follows:
void shuffle(List list) void shuffle(List list, Random rnd)
The following code shows how to use the shuffle methods.
import java.util.ArrayList; import java.util.Collections; import java.util.List; //from ww w . j a v a 2s.co m public class Main { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("Java"); list.add("R"); list.add("CSS"); list.add("XML"); Collections.sort(list); System.out.println("List: " + list); Collections.shuffle(list); System.out.println("List: " + list); Collections.shuffle(list); System.out.println("List: " + list); } }
The code above generates the following result.
We can use the reverse()
static method of the
Collections
class to reverse elements in a List
.
void reverse(List list)
The following code shows how to use the reverse()
method.
import java.util.ArrayList; import java.util.Collections; import java.util.List; /*w w w .j av a2 s . c o m*/ public class Main { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("Java"); list.add("R"); list.add("CSS"); list.add("XML"); Collections.sort(list); System.out.println("List: " + list); Collections.reverse(list); System.out.println("List: " + list); } }
The code above generates the following result.
Swapping swaps two elements in a List.
The swap()
static method of the Collections class does
the swapping.
void swap(List list, int i, int j)
i
and j
are indexes of
two elements and they must be between 0 and size - 1,
where size
is the size of the List.
The following code shows how to reorder elements of a List using these methods.
import java.util.ArrayList; import java.util.Collections; import java.util.List; /*www . java 2s . c o m*/ public class Main { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("Java"); list.add("R"); list.add("CSS"); list.add("XML"); Collections.sort(list); System.out.println("List: " + list); // Swap elements at indexes 1 and 3 Collections.swap(list, 1, 3); System.out.println(list); } }
The code above generates the following result.
import java.util.ArrayList; import java.util.Collections; import java.util.List; // w w w . ja v a 2 s. com public class Main { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("Java"); list.add("R"); list.add("CSS"); list.add("XML"); Collections.sort(list); System.out.println("List: " + list); // Rotate elements by 2 Collections.rotate(list, 2); System.out.println("After Rotating by 2: " + list); } }
The code above generates the following result.
We can create a LIFO Queue
view of a Deque
using the asLifoQueue()
static method of the Collections class:
<T> Queue<T> asLifoQueue(Deque<T> deque)
To use a Map's implementation as a Set implementation, use the newSetFromMap()
static method of the Collections class:
<E> Set<E> newSetFromMap(Map<E, Boolean> map)
We can get a read-only view of a collection when passing around collection to other methods and we do not want the called method to modify your collection.
The Collections class offers the following methods to get read-only views of different types of collections:
<T> Collection<T> unmodifiableCollection(Collection<? extends T> c) <T> List<T> unmodifiableList(List<? extends T> list) <K,V> Map<K,V> unmodifiableMap(Map<? extends K,? extends V> m) <K,V> NavigableMap<K,V> unmodifiableNavigableMap(NavigableMap<K,? extends V> m) <T> Set<T> unmodifiableSet(Set<? extends T> s) <T> NavigableSet<T> unmodifiableNavigableSet(NavigableSet<T> s) static <T> SortedSet<T> unmodifiableSortedSet(SortedSet<T> s) <K,V> SortedMap<K,V> unmodifiableSortedMap(SortedMap<K,? extends V> m)
We pass a collection of a specific type and get a read-only collection of the same type.
We can get a synchronized view of a collection using one of the following static methods of the Collections class.
<T> Collection<T> synchronizedCollection(Collection<T> c) <T> List<T> synchronizedList(List<T> list) <K,V> Map<K,V> synchronizedMap(Map<K,V> m) <K,V> NavigableMap<K,V> synchronizedNavigableMap(NavigableMap<K,V> m) <T> NavigableSet<T> synchronizedNavigableSet(NavigableSet<T> s) <T> Set<T> synchronizedSet(Set<T> s) <T> SortedSet<T> synchronizedSortedSet(SortedSet<T> s) <K,V> SortedMap<K,V> synchronizedSortedMap (SortedMap<K,V> m)
Generics provide compile-time type-safety for collections.
The following code has a compile-time error since we are trying to add Integer type value to a Set which can only have String value.
Set<String> s = new HashSet<>(); s.add("Hello"); a.add(new Integer(1)); // A compile-time error
We can bypass the compiler check by using the following code:
Set<String> s = new HashSet< >(); s.add("Hello"); Set s2 = s; s2.add(new Integer(123)); // No runtime exception
We can avoid the above error by using the checked collections. The following static methods of the Collections class returns a checked collection of a specific type:
<E> Collection<E> checkedCollection(Collection<E> c, Class<E> type) <E> List<E> checkedList(List<E> list, Class<E> type) <K,V> Map<K,V> checkedMap(Map<K,V> m, Class<K> keyType, Class<V> valueType) <K,V> NavigableMap<K,V> checkedNavigableMap(NavigableMap<K,V> m, Class<K> keyType, Class<V> valueType) <E> NavigableSet<E> checkedNavigableSet(NavigableSet<E> s, Class<E> type) <E> Queue<E> checkedQueue(Queue<E> queue, Class<E> type) <E> Set<E> checkedSet(Set<E> s, Class<E> type) <K,V> SortedMap<K,V> checkedSortedMap(SortedMap<K,V> m, Class<K> keyType, Class<V> valueType) <E> SortedSet<E> checkedSortedSet(SortedSet<E> s, Class<E> type)
The following code rewrite the code above.
Set<String> checkedSet = Collections.checkedSet(new HashSet<String>(), String.class); Set s2 = checkedSet; s2.add(new Integer(1)); // Throws ClassCastException
The Collections
class can return an immutable empty collection object of each type.
It can also return an empty Iterator. The following code lists such static methods in the Collections class:
<T> List<T> emptyList() <K,V> Map<K,V> emptyMap() <T> Set<T> emptySet() <T> Iterator<T> emptyIterator() <T> ListIterator<T> emptyListIterator()
We can create a collection that has one and only one element using Collections class.
We have to create this kind of collection object when a method accepts a collection as its argument and we have only one object to pass to that method.
Those methods are as follows:
<T> Set<T> singleton(T o) <T> List<T> singletonList(T o) <K,V> Map<K,V> singletonMap(K key, V value)
The following code shows how to use Collections.singleton()
method.
Set<String> singletonSet = Collections.singleton("Lonely"); // Throws a runtime exception since a singleton set is immutable singletonSet.add("Hello");