From : http://java.boot.by/scjp-tiger/

Use capabilities in the java.util package to write code to manipulate a list by sorting, performing a binary search, or converting the list to an array. Use capabilities in the java.util package to write code to manipulate an array by sorting, performing a binary search, or converting the array to a list. Use the java.util.Comparator and java.lang.Comparable interfaces to affect the sorting of lists and arrays. Furthermore, recognize the effect of the "natural ordering" of primitive wrapper classes and java.lang.String on sorting.

Interface Collection<E>

The following method from Collection interface returns an array containing all of the elements in this collection. If the collection makes any guarantees as to what order its elements are returned by its iterator, this method must return the elements in the same order.

The returned array will be "safe" in that no references to it are maintained by this collection. (In other words, this method must allocate a new array even if this collection is backed by an array). The caller is thus free to modify the returned array.

This method acts as bridge between array-based and collection-based APIs:


Object[] toArray()
					
					

The following method from Collection interface returns an array containing all of the elements in this collection; the runtime type of the returned array is that of the specified array. If the collection fits in the specified array, it is returned therein. Otherwise, a new array is allocated with the runtime type of the specified array and the size of this collection:


<T> T[] toArray(T[] a)
					
					

If this collection fits in the specified array with room to spare (i.e., the array has more elements than this collection), the element in the array immediately following the end of the collection is set to null. This is useful in determining the length of this collection only if the caller knows that this collection does not contain any null elements.)

If this collection makes any guarantees as to what order its elements are returned by its iterator, this method must return the elements in the same order.

Like the toArray method, this method acts as bridge between array-based and collection-based APIs. Further, this method allows precise control over the runtime type of the output array, and may, under certain circumstances, be used to save allocation costs.

Suppose l is a List known to contain only strings. The following code can be used to dump the list into a newly allocated array of String:

String[] x = (String[]) v.toArray(new String[0]);
					
Note that toArray(new Object[0]) is identical in function to toArray().

java.util.Arrays.sort()

The sort methods for the primitive types look like:

void sort (type[] array)
void sort (type[] array, int fromIndex, int toIndex)
					
There is a sort method for each primitive type except boolean. The elements in the array are sorted in ascending order.

The second version sorts those elements between the given indices.

For sorting Object types, there are two approaches. For the first approach there are two methods available:

void sort (Object[] array)
void sort (Object[] array, int fromIndex, int toIndex)
					
Here the objects are sorted into ascending order using the "natural ordering" of the elements. The array elements MUST implement the java.lang.Comparable interface and provide the method:
int compareTo (Object)
					

NOTE, String class implements Comparable interface.

This method defines the "natural ordering" such that comparing object x to y results in a negative number if x is lower than y (on a scale that makes sense for the class), equal to 0 if the objects are identical, and a positive number if x is greater than y.

Your compareTo() method must be written to return a negative, zero, or positive integer according to the ordering rules that make sense for the nature of the objects that the class describes.

For the ALTERNATIVE approach to comparing Object arrays, you create an auxiliary class that implements the java.util.Comparator interface and that knows how to compare and order two objects of interest. This technique is particularly useful if you need to sort classes that you CANNOT RE-WRITE to implement the Comparable interface. The Comparator class has two methods:

int compare (Object obj1, Object obj2)
boolean equals (Object obj1, Object obj2)
					

The compare() method should return a negative, zero, or positive integer, according to the ordering rules that you implement, if obj1 is less than, equal to, or greater than obj2. Similarly, the equals() method compares the objects for equality according to the rules you implement. When using the Comparator technique, the two object array sorting methods are:

void sort (Object[] array, Comparator comp)
void sort (Object[] array, int fromIndex, int toIndex, Comparator comp)
					

java.util.Arrays.binarySearch()

Another useful set of overloaded methods in the Arrays class is the set of binary searching methods:

int binarySearch (type[] array, type key)
int binarySearch (Object[] array, Object key, Comparator comp)
					

There is an overloaded binarySearch() method for each primitive type except boolean and one more for Object. These methods search an array for the given key value. Returns index of the search key, if it is contained in the list. The array to be searched *MUST* be sorted first in ascending order, perhaps by using one of the sort() methods. If it is not sorted, the results are UNDEFINED. If the array contains multiple elements with the specified value, there is NO guarantee which one will be found.

The methods return the index of the search key, if it is contained in the list; otherwise, (-(insertion_point) - 1). The insertion_point is defined as the point at which the key would be inserted into the array: the index of the first element greater than the key, or array.length, if all elements in the array are less than the specified key.

NOTE, this guarantees that the return value will be >= 0 if and only if the key is found.

For the case of Object arrays and the first type of binarySearch() method above, the elements must implement the Comparable interface. If you cannot change the classes to implement this interface, then you can provide a Comparator and use the second type of binarySearch() method shown above.

The class Arrays, provides useful algorithms that operate on arrays. It also provides the static asList() method, which can be used to create List views of arrays. Changes to the List view affects the array and vice versa. The List size is the array size and CANNOT be modified. The asList() method in the Arrays class and the toArray() method in the Collection interface provide the bridge between arrays and collections:

Set mySet = new HashSet(Arrays.asList(myArray));
					
String[] strArray = (String[]) mySet.toArray();
					

The asList(...) method of java.util.Arrays class returns a fixed-size list backed by the specified array. Changes to the returned list "write through" to the array. This method acts as bridge between array-based and collection-based APIs, in combination with Collection.toArray. The returned list is serializable and implements RandomAccess.

This method also provides a convenient way to create a fixed-size list initialized to contain several elements:

List stooges = Arrays.asList("Larry", "Moe", "Curly");
					

public static <T> List<T> asList(T... a)
					
					

java.util.Comparator interface:

					
package java.util;

public interface Comparator<T> {
	int compare(T o1, T o2);
	boolean equals(Object obj);
}

					

java.lang.Comparable interface:

					
package java.lang;

public interface Comparable<T> {
	public int compareTo(T o);
}

					

java.util.Collections

This class consists exclusively of static methods that operate on or return collections. It contains polymorphic algorithms that operate on collections, "wrappers", which return a new collection backed by a specified collection, and a few other odds and ends.

The following method sorts the specified list into ascending order, according to the natural ordering of its elements. All elements in the list MUST implement the Comparable interface. Furthermore, all elements in the list must be mutually comparable (that is, e1.compareTo(e2) must not throw a ClassCastException for any elements e1 and e2 in the list).

The specified list must be modifiable, but need not be resizable.

This implementation dumps the specified list into an array, sorts the array, and iterates over the list resetting each element from the corresponding position in the array:


public static <T extends Comparable<? super T>> void sort(List<T> list)

					

The following method sorts the specified list according to the order induced by the specified comparator. All elements in the list MUST implement the Comparable interface. Furthermore, all elements in the list must be mutually comparable (that is, e1.compareTo(e2) must not throw a ClassCastException for any elements e1 and e2 in the list).

The specified list must be modifiable, but need not be resizable.

This implementation dumps the specified list into an array, sorts the array, and iterates over the list resetting each element from the corresponding position in the array:


public static <T> void sort(List<T> list, Comparator<? super T> c)

					

With the help of the method sort(list, comparator) you can for example sort the list in reverse order:

/** Non-Comparable class */
public class WeirdString { 
	private String str;
	
	WeirdString(String str ){
		this.str = str;
	}
}					
					
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;

public class ReverseClient {
	
	public static void main(String ... sss) {
		List myList = new LinkedList();
		String s1 = new String("2345");
		String s2 = new String("12345");		
		String s3 = new String("45");
		String s4 = new String("345");
		WeirdString s5 = new WeirdString("345");
		
		myList.add(s1);
		myList.add(s2);
		myList.add(s3);
		myList.add(s4);
		// myList.add(s5); // WRONG ! See *)
		
		System.out.println("Original list : " + myList);		
		Comparator cmp = Collections.reverseOrder();
		// *) The 'sort(list, comp)' method may throw ClassCastException 
		// if the list contains elements that are not *mutually* 
		// comparable using the specified comparator
		Collections.sort(myList, cmp); 		
		System.out.println("Sorted list (descending order) : " + myList);
	}	
}					
					
The output of the ReverseClient class will be:
Original list : [2345, 12345, 45, 345]
Sorted list (descending order) : [45, 345, 2345, 12345]					
					

The following method searches the specified list for the specified object using the binary search algorithm. The list MUST be sorted into ascending order according to the natural ordering of its elements (as by the sort(List) method) prior to making this call. If it is not sorted, the results are UNDEFINED. If the list contains multiple elements equal to the specified object, there is NO guarantee which one will be found.

Returns index of the search key, if it is contained in the list; otherwise, (-(insertion_point) - 1). The insertion_point is defined as the point at which the key would be inserted into the list: the index of the first element greater than the key, or list.size(), if all elements in the list are less than the specified key. NOTE, that this guarantees that the return value will be >= 0 if and only if the key is found:


public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key)

					

This code sample demonstrates sort(...) and binarySearch(...) methods:

/** Non-Comparable class */
public class WeirdString { 
	private String str;
	
	WeirdString(String str ){
		this.str = str;
	}
}					
					
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

public class CollClient {
	
	public static void main(String ... sss) {
		List myList = new LinkedList();
		String s1 = new String("2345");
		String s2 = new String("12345");		
		String s3 = new String("45");
		String s4 = new String("345");
		WeirdString s5 = new WeirdString("345");
		
		myList.add(s1);
		myList.add(s2);
		myList.add(s3);
		myList.add(s4);
		// myList.add(s5); // WRONG ! See *)
		
		System.out.println("Original list : " + myList); 
		// Result may be invalid if collection unsorted in *ascending* order!!!
		// *) May throw ClassCastException if the list contains 
		//    elements that are not *mutually* comparable !!!
		System.out.println("45 : " + Collections.binarySearch(myList, "45"));
		System.out.println("99 : " + Collections.binarySearch(myList, "99"));
		// *) May throw ClassCastException if the list contains 
		//    elements that are not *mutually* comparable !!!
		Collections.sort(myList); // sort in ascending order 
		System.out.println("Sorted list (ascending order): " + myList);
		System.out.println("45 : " + Collections.binarySearch(myList, "45"));
		System.out.println("99 : " + Collections.binarySearch(myList, "99"));
	}	
}
					
The output:
Original list : [2345, 12345, 45, 345]
45 : 2
99 : -5
Sorted list (ascending order): [12345, 2345, 345, 45]
45 : 3
99 : -5					
					

The following method searches the specified list for the specified object using the binary search algorithm. The list MUST be sorted into ascending order according to the specified comparator (as by the sort(List, Comparator) method, ), prior to making this call. If it is not sorted, the results are UNDEFINED. If the list contains multiple elements equal to the specified object, there is NO guarantee which one will be found.

c - the comparator by which the list is ordered. A null value indicates that the elements' natural ordering should be used.

The method returns index of the search key, if it is contained in the list; otherwise, (-(insertion_point) - 1). The insertion point is defined as the point at which the key would be inserted into the list: the index of the first element greater than the key, or list.size(), if all elements in the list are less than the specified key. NOTE, this guarantees that the return value will be >= 0 if and only if the key is found.


public static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c)

					

The following code sample shows how to reverse the list of objects:

/** Non-Comparable class */
public class WeirdString { 
	private String str;
	
	WeirdString(String str ){
		this.str = str;
	}
}					
					
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;

public class ReverseListClient {
	
	public static void main(String ... sss) {
		List myList = new LinkedList();
		String s1 = new String("2345");
		String s2 = new String("12345");		
		String s3 = new String("45");
		String s4 = new String("345");
		WeirdString s5 = new WeirdString("345"); 
		
		myList.add(s1);
		myList.add(s2);
		myList.add(s3);
		myList.add(s4);
		myList.add(s5); // OK, no need to be mutually comparable
		
		System.out.println("Original list : " + myList);
		Collections.reverse(myList); // OK
		System.out.println("Reversed list : " + myList);
	}	
}					
					
The code sample's output will be (reversed list):
Original list : [2345, 12345, 45, 345, WeirdString@1f6a7b9]
Reversed list : [WeirdString@1f6a7b9, 345, 45, 12345, 2345]