Type-casting is both annoying and dangerous, but it has to be done when pulling elements out of an ArrayList. Or does it? In version 1.5, Java introduced type placeholders, known as generics.
Instead of defining an ArrayList the normal way, like this:
public static void main(String[] args) { ArrayList names = new ArrayList(); names.add("Bahram"); names.add("Anika"); names.add("Hugo"); String firstName = (String) names.get(0); System.out.println("Is the first name Bahram? " + firstName.equals("Bahrom")); }
... we can specify a generic type for the ArrayList:
public static void main(String[] args) { ArrayList<String> names = new ArrayList<String>(); names.add("Bahram"); names.add("Anika"); names.add("Hugo"); String firstName = names.get(0); System.out.println("Is the first name Bahrom? " + firstName.equals("Bahrom")); }
Here's what changed:
names
now has type ArrayList<String>
, which specifies the generic type. Now only strings can be added to names
.
Any method that returns elements from the list will return things of the generic type. Thus, type casting may be unnecessary.
Additionally, when calling the constructor, you can leave out the type inside the triangle-brackets before the parentheses like this:
public static void main(String[] args) { ArrayList<String> names = new ArrayList<>(); names.add("Bahram"); names.add("Anika"); names.add("Hugo"); String firstName = names.get(0); System.out.println("Is the first name Bahrom? " + firstName.equals("Bahrom")); }
In this case, Java automatically assumes you want the generic type used in the variable declaration. You can't leave that out!
On the other hand, you might want to create a class that uses generics. Although we can't see the source code for the ArrayList class, here's what the signature probably looks like:
public class ArrayList<ElementType extends Object> {
ElementType
is the name of the placeholder that will be used throughout the code. If we wanted to only allow certain types of objects, then we could change the type the placeholder extends. (Notice the name of the placeholder is different as well as the super type in this example.)
public class ZooExhibit<AnimalType extends Mammal> {
Back to ArrayList! In the method definitions, the placeholder is used to refer to the type. This is what I expect the signature for ArrayList.get looks like:
public ElementType get(int index) {
Create an ArrayList<Horse>
and add a bunch of horses and zebras. Then traverse the array-list and print each horse (zebras too!) out.