Last class we looked at ArrayList<String>, the easiest case. We saw that works much like a String array, but is stretchy. Now turn to numeric types, to be able to use stretchy arrays of numbers.
However, there is no such thing as ArrayList<int>. Java only supports object types inslde <>, i.e., as type parameters, and int and double are primitive types, not object types.
Integer and Double: wrapped int and double
An Integer is an object that holds an int value.
Integer x = new Integer(6);
Here x is an object that holds a 6 inside it. More precisely, x is the name of an object reference that points to an Integer object holding a 6 inside it.
Double d = new Double(2.3);
Here d is an object that holds 2.3 inside it. More precisely, d is the name of an object reference that points to an Double object holding 2.3 inside it.
Because Integer and Double are object types, we can use ArrayList<Integer> and ArrayList<Double>.
But first, we need to understand “auto-boxing” and “unboxing”, at least for easy use of these powerful lists.
We can simply put
Integer x = 6; // Here the int 6 is converted (auto-boxed) into an Integer object
int y = x; // the value inside Integer x is put in int y, unboxed
This makes working with ArrayList<Integer> pretty easy:
ArrayList<Integer> nums = new ArrayList<Integer>();
nums.add(4);
nums.add(-2);
nums.add(10);
System.out.println(nums);
Prints: [4, -2, 10]
int x = nums.get(0); // unboxed on way out
<<picture of nums, with array of 3 refs, each pointing to an Integer object>>
Compare this with an array:
Int[] nums = new int[3];
nums[0] = 4;
nums[1] = -2;
nums[2] + 10;
//need loop to print them out, or use Arrays.toString(nums); (see pg. 448)
Feature of arrays: can set up the above array by
Int[] nums = {4, -2, 10};
There’s no such nifty initializer for ArrayLists. Of course you can set up an array and then use those values to fill an ArrayList.
Example using Double: input doubles from a file nums.dat, output them in opposite order by filling an ArrayList<Double>.
Use code from pg. 380 again, modifying as needed:
Scanner input = new Scanner(new File(“nums.dat”));
ArrayList<Double> nums = new ArrayList<Double>();
while (input.hasNextDouble()) {
double d = input.nextDouble();
nums.add(d); // boxed from double to Double
}
for (int i=nums.size()-1; I >= 0; i--) {
System.out.println(nums.get(i));
}
Sorting Strings, Integers, Doubles
Integers and Doubles have a natural ordering, going from negative values, then 0, then positive values, larger and larger. So sorting an array or ArrayList of doubles/Doubles has a clear meaning. Strings also have a certain order, but it’s not as simple as you might think.
We say “apple” is before “banana”, which is before “batton”, etc., just alphabetical order. However, it matters greatly whether the letters are in uppercase or not. All the characters are in order like this:
…0123456789…ABC…XYZ…abc…xyz…
so A is before a, and even Z is before a. Thus “Zebra” is before “apple”. To make things simple, we will follow the text’s lead and just use lowercase in sorting examples.
Look at SortExample, pg. 646 and on the text’s website.
The sort is carried out by the line
Collections.sort(words);
And to use this, we need the import at the top of the program.
We ran this program in class, and then changed “years” to “Years”, and saw that this made Years show up at the start of the sorted list.
We converted the program to sort Integers in an ArrayList<Integer> instead of Strings.
Then, to see the parallel case of arrays of ints, we changed it to use an array of int:
int[] nums = {4, -2, 10};
Arrays.sort(nums);
Arrays.toString(nums); // or write a loop
// see sorted array
Note that for an array you use Arrays.sort, and for an ArrayList, Collections.sort.
How does sorting work?
It involves many comparisons of pairs of values: 4 vs. -2, -2 vs 10, etc. Let’s look into how to compare values.
For primitive types, we can use x < y for example, but this does not work for objects, so we cannot say “apple” < “banana” in Java, though we could do this in some other languages.
For object types, we need a method, and the standard method is named compareTo.
For String:
int compareTo(String other);
String x = “hello”;
String y = “world”;
Int result = x.compareTo(y)
The int result is used to express three cases:
result < 0 means x is before y in String order
result > 0 means x is after y in String order
result == 0 means x is same as y in String order , so x.equals(y)
Similarly with Integer and Double—see pg. 649
See the useful table on pg. 652.
So we have
For String:
int compareTo(String other);
For Integer:
int compareTo(Integer other);
For Double:
int compareTo(Double other);
We see a pattern of same-named method across classes—how can we capture this in Java?
With an interface, though more advanced form than before, because it needs a type parameter:
public interface Comparable<T> {
int compareTo(T other);
}
See this on pg. 649.
Next time: making our own classes that implement Comparable<T>, so we can sort arrays and ArrayLists of our own objects.