Comparison of Array and ArrayList
ArrayLists are like arrays, but the main advantage is that they can increase (and decrease) in size.
You can specify a capacity, but the ArrayList class automatically increases the list's capacity whenever necessary.
Array | ArrayList | HashMap | |
---|---|---|---|
resizable | no | yes | yes |
contain primitives | yes | no | no |
contain objects | yes | yes | yes |
iterating values ??? | for, for each | iterator, for each | |
find length | .length variable | .size() method | same as arraylist |
performance | fast | slow in comparision ? | |
multidimensional | yes | no (only 1D) | same as arraylist |
order maintained | yes | yes | no |
duplicate elements | yes | yes | no |
add elements | assignment operator (=) | .add() method | same as arraylist |
You can make an ArrayList of any type of object, but you need to specify the object when you make it.
ArrayList is a parameterized type (also known as a generic collection).
A parameterized type can take a type parameter, so that from the single class ArrayList,
we get a multitude of types including ArrayList<String>
, ArrayList<JButton>
,
and in fact ArrayList<T>
for any object type T.
The type parameter T must be an object type such as a class name or an interface name.
It cannot be a primitive type. This means that, unfortunately, you can not have an ArrayList of int or an ArrayList of char.
In generic collection, we specify the type in angular braces. Now ArrayList is forced to have only specified type of objects in it. If you try to add another type of object, it gives compile time error.
Syntax:
ArrayList<Person> people = new ArrayList<Person>();"people" is the name of the arraylist
new
and ()
.
add(object) | add object to the end of the array list | most common method |
add(index, object) | add object to postion index | everything else gets pushed back. If there is nothing already at index, you'll get an exception. |
get(index) | return the object that is at postion index | very useful |
remove(object) | remove the first object that is the same as "object" | it uses .equals() to check |
remove(index) | remove the object that is at postion index | |
set(index, object) | replace the object at index with the new object | |
indexOf(object) | return the index of the first occurrence of object | |
Other methods: clear(), removeAll(), removeRange() ... |
Depending on what you want to do, you can
(i) add existing objects [not shown here],
(ii) create the object separately and then add it to the array list, or
(iii) create the object in the array list method
ArrayList<Book> bookshelf = new ArrayList<Book>(); //(ii) here we make the bk object, then add it to the arraylist Book bk = new Book("West Side Story", 1950); bookshelf.add(bk); //since we don't need to keep the bk object we can reuse it bk = new Book("East of Eden", 1939); bookshelf.add(bk); //(iii) here the Book object never is named, so there is no way to reference it (but we don't need to) bookshelf.add(new Book("Life of Pi", 1950)); bookshelf.add(new Book("Tintin", 1955));
There are three methods. You should be familiar with each. The third one is a bit complicated
I. For Loop
void print1(ArrayList<Book> bs) { System.out.printf("%-25s %s%n", "Title", "Pubdate"); for (int i = 0; i < bs.size(); i++) { Book b = bs.get(i); System.out.printf(" %-25s %d%n", b.title, b.pubdate); } }
OUTPUT: ======= Title Pubdate West Side Story 1950 East of Eden 1966 Life of Pi 1950 Tintin 1955
II. For each loop
void print2(ArrayList<Book> bs) {
System.out.printf("%-25s %s%n", "Title", "Pubdate");
for (Book b : bs) {
System.out.printf(" %-25s %d%n", b.title, b.pubdate);
}
}
OUTPUT: ... same as above ...
III. using Iterator
void print3(ArrayList<Book> bs) { System.out.printf("%-25s %s%n", "Title", "Pubdate"); Iterator<Book> it = bs.iterator(); while ( it.hasNext() ) { Book b = it.next(); System.out.printf(" %-25s %d%n", b.title, b.pubdate); } }
OUTPUT: ... same as above ...
This is complicated because when you delete something in the list everything else has to move backwards. ...
Again, we can do it using any of the three ways of looping over the list
1. FOR LOOP:
for (int i = 0; i < bs.size(); i++) { Book b = bs.get(i); if (b.pubdate == 1950) { bs.remove(i); i--; // Important! Add this in. } }
This works and it deletes the item, BUT it will then skip over the next item. So you can never delete two consecutive entries!
If you are deleting and printing the list at the same time, it will skip over the item after the one you delete and not print it.
Solution:
1. add the line i--;
see above
2. Go through the arraylist backwards. Each item can be checked (and printed).
for (int i = bs.size()-1; i >= 0; i--) { Book b = bs.get(i); if (b.pubdate == 1950) bs.remove(i); }
2. FOR-EACH LOOP:
for (Book b : bs) {
if (b.pubdate == 1950) bs.remove(b); //ERROR: java.util.ConcurrentModificationException
}
Look, a for-each loop is really the nicest and simplest way of going through a list.
HOWEVER, it dies when you try and delete something! (Actually, only when you try and read the next item.)
You are trying to modify the list while you are reading it (perhaps it is copied to memory? I don't know the guts of it.)
Solution: You have to BREAK immediately to avoid this error, which means that you can only ever delete one item at a time.
3. ITERATORS:
Iterator<Book> it = bs.iterator(); while ( it.hasNext() ) { Book b = it.next(); if (b.pubdate == 1950) it.remove(); }
This works!!! No problems at all. Except ... you have to remember the syntax for iterators.
I haven't ever had the need to do this (and I haven't actually tested this either)
// converting an array to an ArrayList, with Generics
String[] animals = { "bear", "cougar", "wolverine"};
ArrayList<String> al = new ArrayList<String>( Arrays.asList( animals ) );
// converting an ArrayList to an array with generics.
String[] predators = al.toArray( new String[ al.size() ] );