Java: Arrays

At its most basic, an array is just an ordered list, containing all the same type of object (or primitive). You can define an array variable using some pretty simple code. Which of the following lines do you think are valid java?

int[] myArray;
int [] myArray2;
int myArray3[];
int myArray4 [];

You should be used to this by now, but they all are, although please never declare arrays like that, the standard convention is on line 1. But all we’ve got above are blank array variables, pointing to null (in the same way that writing String myString;  just gives you a null string variable). To instantiate the array we can use the following lines.

int[] myArray = new int[10]; //Creates an array with 10 slots (0-9)
int[] myOtherArray = {1,2,3,4,5}; //5 slot array

Accessing values in an array is as simple as writing arrayName[index] to return the value you want to get.

There are several important things to remember about arrays. Once you’ve created one and set its size, its size cannot change. If you set a new integer array to have size 10, and set the first value of that array to 5, the length of the array is still 10, every other slot in the array just has a value of null. While we’re on that topic, making a string (for example) array of size 10 does not give you an array that holds 10 strings. It gives you an array with 10 slots, each of which will hold a pointer to a string. This makes sense if you think about it, as strings could potentially be very long, so there’s no possible way the JVM could make a 10 slot array with unlimited space in each slot just on the off chance you want to store all of The Order of the Phoenix in a single string and store it in slot 1. I’m using strings as an example, but this is true regardless of the object.

As mentioned in previous posts, trying to access an array index that doesn’t exist will throw a runtime exception. See the code examples below:

int[] numbers = new int[10];

numbers[10] = 3;
numbers[numbers.length] = 5;

for(int i=0; i <= numbers.length; i++){
	numbers[i] = i + 5;
}

So, we have three lines accessing the array, at 3, 4, and 7. Line 3 throws an exception because it's trying to access the eleventh slot in the array (remember counting slots starts at 0). Line 4 doesn’t work for the same reason, the length of the numbers array is 10, which means the slots that exist range from 0 to 9. Finally, line 7 throws an exception for the same reason, the end condition for the loop means that it will run when i is equal to 10, which will cause the problem.

Sorting & Searching

Sorting an array is pretty easy, thanks to the built in sorting utility. It’s use is shown below:

int[] myNumbers = {5, 3, 8};
Arrays.sort(myNumbers);
for(int i=0; i < myNumbers.length; i++){
	System.out.println(myNumbers[i] + " "); //Prints 3 5 8
}

Note that the values in the original array itself are modified, a new array is not returned when calling the sort function. This function call also be used to sort string arrays alphabetically. It is possible to write your own sort implementation for arrays storing more complex objects, but that's outside the scope of this post.

Searching through an array is likewise pretty easy, but there's some caveats. First, and most importantly, the array must be sorted before you search through it, otherwise you’ll get completely unpredictable results. You call the search using the following code:

Arrays.binarySearch(myNumbers, 5); //Returns 1

The search has three potential outcomes. If what you are looking for is found, it will return the index position of that item. If it is not found, we get back a negative value 1 smaller than the location the item being searched for would need to be inserted in order to preserve the order of the elements in the array. This is because getting a negative number tells you that the item hasn’t been found (there’s no such thing as a negative index in an array). Why is one subtracted from that value? Well, in the case where something would need to be inserted at index 0, the search can’t return a -0, so it subtracts one from that value, giving -1 as the return. That convention is kept for all locations a value would need to be inserted in.
Finally, if the array is not sorted, any number might be returned, it will be an unpredictable result, so you should not trying using a binary search on an unsorted array (or using a binary search on anything that’s unsorted, that’s not how binary searches work!).

ArrayLists

Arraylists are lists that are arrays. Alright, next post!

….Ok, ok. Arraylists are like arrays, but better. They’re almost like what a stringbuilder is to a string. You get some useful functions attached to arraylists, and their size can be increased or decreased as needed, usually automatically, which you can’t do with an array. Below are some typical ways to make a new arraylist.

ArrayList list1 = new ArrayList();
ArrayList list2 = new ArrayList(10);
ArrayList list3 = new ArrayList(list2);
ArrayList list4 = new ArrayList();

Line 1 should be fairly self explanatory, on line 2 we’re creating a new arraylist (I never realised before how long that word takes to type out when you’re using it this many times) and setting it’s length to 10 (though remember this may increase or decrease later as needed). Line 3 makes a new array list, but in it stores a

    copy

of what is in list2. Line 4 creates a new arraylist, stating that it will hold objects of type string. In all other lines there, the arraylist is assumed to be holding values of type Object (the base type of object in Java, which all other objects inherit from). One final thing to note is that the arraylist implements the list interface, so you can store an arraylist in a list reference variable, but not the other way around.
Moving on, lets focus on fairly fun functions for (f)working with arraylists (I tried). Fortunately, most of these functions are pretty self-explanatory in what they do.

add()
Pass in the object you want to add, it gets put at the end of the list. Just make sure you match the type of object you’re passing in to the object type the list is.

remove(Object object)/remove(int index)
This will remove the first matching value in the arraylist, or will remove the item at the index you pass in. Passing in an object will return a boolean if the object is removed, passing in an index will return a reference to the object that’s been removed from the list. If you pass in an index that doesn’t exist (passing in 3 on an arraylist that only has two items), a runtime exception will occur.

set(int index, Object element)
This will change one of the elements in the arraylist. It returns the object that got replaced. Again, trying to replace an element at an index that doesn’t exist will cause an exception to be thrown.

isEmpty()/size()
Pretty much what it says on the tin. Just remember that size will return the number of slots that are in use, not the capacity of the arraylist.

clear()
Removes all elements from the arraylist.

contains(Object object)
Will return true if the arraylist contains the object passed in. This function will call the equals function on each element in the array.

equals(Object object)
This is used to compare two arraylists, to see if they contain the same elements in the same order. Again, this is done using the equals function on each element in the arraylist. For example, in the case of an arraylist filled with strings, it will compare the content of each string, rather than the objects themselves.

One more useful utility, you can sort an arraylist using the following code:

ArrayList myNumbers = new ArrayList();
myNumbers.add(5);
myNumbers.add(2);
myNumbers.add(8);
Collections.sort(numbers);
System.out.println(numbers); //prints [2,5,8]

Just don’t forget to import from the Collections package, like I didn’t do in the code above ;-).

Backed Lists

Just when you thought we were done! One more interesting thing is the concept of a backed list. If you have an array, and convert it to an arraylist, as below, you get an arraylist with a fixed size, which is linked to the original array. This means that changing the value in one, changes the value in the other, and you cannot add/remove items to the arraylist (because that would then require the backing array to have its size changed, which isn’t possible).

String[] birds = {"hawk", "crow", "robin"};
List myList = Arrays.asList(birds); //myList is a backed arraylist, with a fixed size

Like some of my other posts, there’s more to arrays than what I listed above, but this is a pretty good overview of some of the more common features.

Leave a comment