Tuesday, 21 September 2010

Arrays in java - Some more library functions

Java is known for its library. You can write the simple programs like arraycopy etc, but why to write
them if you know the logic already, and so why not simply use them. So here is what java is useful for a lot.

Static methods for manipulating arrays are available in the java.util.Arrays and java.System classes. Assume the following declarations, where T is the array element type, either a primitive, object or either kind of type depending on which method is being called. 

T       x, key;  // This type T can be either a primitive or object type.
T[] a, a2; // This type T can be either a primitive or object type.
List lst; // Only object types T.
Comparator comp; // Only object types T.
int i; // Index returned from search.
int i1, i2;
int from; // Lower bound of subscript range. Includes this element.
int to; // Upper bound of subscript range. Does not include this element.
String s;
boolean b; // Normally the method result will be used in an if.
lst = Arrays.asList(a); List based on the array.
s = Arrays.toString(a);String form surrounded by "[]", elements separated
by ", ".
s = Arrays.deepToString(a);String form by recursively converting subarrays.
b = Arrays.equals(a, a2);True if arrays are same size and all elements are
equal (== or equals as appropriate).
b = Arrays.deepEquals(a, a2);As above, recursively applied to subarrays.
Arrays.fill(a, x); Fills array with a value.
Arrays.fill(a, from, to, x); Fills subrange (from inclusive, to exclusive) with a value.
Making a copy of part of an array
System.arraycopy(a, i1, a2, i2, len); Shallow copy len elements from a[i1] to a2[i2]. Case!
a2 = Arrays.copyOf(a, newLength); New shallow copy of array with new length. If longer, uses default values.
a2 = Arrays.copyOfRange(a, from, to); New shallow copy of portion of array.
Searching
i = Arrays.binarySearch(a, key);A O(log N)search of array sorted in ascending order. If the key is not found, a negative number, -insertionPoint-1, is returned.
i = Arrays.binarySearch(a, key, comp);Binary search of a sorted array of objects (not primitives).
Sorting. See Sorting Arrays for more on sorting and comparators.
Arrays.sort(a); Sorts in "natural" order. If object type, elements must be comparable.
Arrays.sort(a, comp); Sorts objects (not primitives) using comparator.
Arrays.sort(a, from, to); Sorts subrange, including a[from] excluding a[to].
Arrays.sort(a, from, to, comp);Sorts objects (not primitives) in subrange using comparator.

Use java.util.Arrays.toString(...) for debugging

AVOID default toString(). Using the common debugging technique of printing intermediate values on the console with arrays is good, but requires calling a library method to get the results you expect. Arrays are a subclass of Object as ever other object is, and therefore the toString() method is defined for every array. The results will very likely disappoint you.
String[] abc = {"a", "b", "c"};
System.out.println(abc); // println calls toString() on object parameters.
This displays the relatively unhelpful "[L", element type, ";@", and hexadecimal memory address of the array.
[Ljava.lang.String;@f6f1b6
USE java.util.Arrays.toString(...) and you'll get something much more readable. An import java.util.*; statement avoids the extra package qualifier.
String[] abc = {"a", "b", "c"};
System.out.println(java.util.Arrays.toString(abc));
This produces the following output, which is the same as toString() applied to a List.
[a, b, c]

Use Arrays.asList(...) for Collections view of array

Make a list. The Arrays class has some useful methods for working with arrays, but there are a lot more
if you make your array look like a List. The Collections class has many useful methods,
eg, shuffle, reverse, max, .... See Collections Class.
import java.util.*;
. . .
List listabc = Arrays.asList(abc);
// The Collections methods can now be use with listabc.
View of underlying array. The list that is created is not a regular ArrayList. It is based only
on the original array, so you can't do things like adding elements to the list because this would
cause reallocation of a larger underlying array.
Uses the underlying array. One of the really nice things about this is that you can still use the
underlying array, which means that creating this list doesn't prevent you from taking advantage
of the efficiency of array access for example.
Objects only. The java.util.Arrays.asList(...) method only works for arrays of object types.
If you try to use it with an array of primitives, you will get a compilation error.

Shuffling (randomizing) an array

import java.util.*;
. . .
List labc = Arrays.asList(abc);
. . .
Collections.shuffle(labc);
System.out.println(labc);
Which gave the following output. Note that the List overrides toString() to give reasonable
output.
[b, a, c]
Inefficient? Not necessarily. Constructing a new List object from the array is only inefficient if
you're doing it frequently. If you do it very often then you want to avoid creating a new list each time.
Creating the list one time is not a problem because the list that is produced is backed by this one array
-- you can change elements in the array and the list will reflect those changes.

Can't shuffle arrays of primitives this way!

Lists and other Collections classes only work on objects, not on primitive values, so you have to
do the shuffling "by hand". See Random Numbers - shuffling for how to do it yourself.

No comments:

Post a Comment