Array List
Java's
List
interface (java.util.List
) can be generified. In other words, instances of List
can be given a type, so only instances of that type can be inserted and read from that List
. Here is an example:List<String> list = new ArrayList<String>;
This list is now targeted at only
String
instances, meaning only String
instances can be put into this list. If you try to put something else into this List
, the compiler will complain.
The generic type checks only exists at compile time. At runtime it is possible to tweak your code so that a String List has other objects that String's inserted. This is a bad idea, though.
Accessing a Generic List
You can get and insert the elements of a generic
List
like this:List<String> list = new ArrayList<String>; String string1 = "a string"; list.add(string1); String string2 = list.get(0);
Notice how it is not necessary to cast the object obtained from the
List.get()
method call, as is normally necessary. The compiler knows that this List
can only contain String
instances, so casts are not necessary.Iterating a Generic List
You can iterate a generic
List
using an iterator, like this:List<String> list = new ArrayList<String>; Iterator<String> iterator = list.iterator(); while(iterator.hasNext()){ String aString = iterator.next(); }
Notice how it is not necessary to cast the object returned from the
iterator.next()
next call. Because theList
is generified (has a type), the compiler knows that it contains String
instances. Therefore it is not necessary to cast the objects obtained from it, even if it comes from its Iterator
.
You can also use the new for-loop, like this:
List<String> list = new ArrayList<String>; for(String aString : list) { System.out.println(aString); }
Notice how a
String
variable is declared inside the parantheses of the for-loop. For each iteration (each element in the List
) this variable contains the current element (current String).
Set
Java's
Set
interface (java.util.Set
) can be generified. In other words, instances of Set
can be given a type, so only instances of that type can be inserted and read from that Set
. Here is an example:Set<String> set = new HashSet<String>;
This set is now targeted at only
String
instances, meaning only String
instances can be put into this set. If you try to put something else into this Set
, the compiler will complain.
The generic type checks only exists at compile time. At runtime it is possible to tweak your code so that a String Set has other objects that String's inserted. This is a bad idea, though.
Adding Elements to a Generic Set
Adding elements to a generic
Set
is done using the add()
method, just like you have always done:Set<String> set = new HashSet<String>; String string1 = "a string"; set.add(string1);
So what is the big difference? Well, if you try to add an element that is not a
String
instance, to the Set
in the example above, the compiler will complain. That's a pretty nice extra type check to have.
Iterating a Generic Set
You can iterate a generic
Set
using an iterator, like this:Set<String> set = new HashSet<String>; Iterator<String> iterator = set.iterator(); while(iterator.hasNext()){ String aString = iterator.next(); }
Notice how it is not necessary to cast the object returned from the
iterator.next()
next call. Because theSet
is generified (has a type), the compiler knows that it contains String
instances. Therefore it is not necessary to cast the objects obtained from it, even if it comes from its Iterator
.
You can also use the new for-loop, like this:
Set<String> set = new HashSet<String>; for(String aString : set) { System.out.println(aString); }
Notice how a
String
variable is declared inside the parantheses of the for-loop. For each iteration (each element in the Set
) this variable contains the current element (current String).
Map
Java's
Map
interface (java.util.Map
) can be generified. In other words, you can set the specific type of both the keys and values in a generic Map
instance. Here is an example:Map<Integer, String> set = new HashMap<Integer, String>;
This
Map
can now only accept Integer
instances as keys, and String
instances as values.
The generic type checks only exists at compile time. At run time it is possible to tweak your code so that other instances can be inserted. This is a bad idea, though.
Accessing a Generic Map
Adding and getting elements to a generic
Map
is done using the put()
and get()
methods, just like you have always done:Map<Integer, String> map = new HashMap<Integer, String>; Integer key1 = new Integer(123); String value1 = "value 1"; map.put(key1, value1); String value1_1 = map.get(key1);
So what is the big difference? Well, if you try to add a key, value pair that is not a
Integer, String
pair instance, to the Map
in the example above, the compiler will complain. That's a pretty nice extra type check to have.
Also notice how it is not necessary to cast the
String
instance returned by the get()
method. The compiler knows that this Map
has String
values, so casting is not necessary.
You can also use the new auto boxing features of Java 5 to make it easier to specify the
Integer
values, like this:Map<Integer, String> map = new HashMap<Integer, String>; Integer key1 = 123; String value1 = "value 1"; map.put(key1, value1); //or map.put(123, value1); String value1_1 = map.get(123);
Iterating a Generic Map
A
Map
has two collections you can iterate. The key Set
and the value Set
. Most often you iterate the key Set
and access the values for each key via the Map.get()
method.
Here are two examples:
Map<Integer, String> map = new HashMap<Integer, String>; //... add key, value pairs to the Map // iterate keys. Iterator<Integer> keyIterator = map.keySet().iterator(); while(keyIterator.hasNext()){ Integer aKey = iterator.next(); String aValue = map.get(aKey); } Iterator<String> valueIterator = map.values().iterator(); while(valueIterator.hasNext()){ String aString = valueIterator.next(); }
Notice how it is not necessary to cast the object returned from the
iterator.next()
next call. Because theMap
is generified (has a type), the compiler knows that it contains Integer
instances for keys, and String
instances for values. Therefore it is not necessary to cast the objects obtained from the Map
, even if it comes from one of its Iterator
's.
You can also use the new for-loop, like this:
Map<Integer, String> map = new HashMap<Integer, String>; //... add key, value pairs to the Map for(Integer aKey : map.keySet()) { String aValue = map.get(aKey); System.out.println("" + aKey + ":" + aValue); } for(String aValue : map.values()) { System.out.println(aValue); }
Notice how an
Integer
and a String
variable is declared inside the parantheses of each for-loop. For each iteration (each element in the Map
's key set or value collection) this variable contains the current element (current Integer or String).
No comments:
Post a Comment