Java Collections API
• Java Collections API
• Introduction to generics in Java
• Lists
• Stacks and queues
• Sets
• Maps
• Summary
Outline
• The Java Collections API provides an
implementation of all the data structures we have
seen so far.
• It is not necessarily the best implementation
available, but its ready-made.
• We will familiarize ourselves with how to use it:
users of data structures only need to see the
available operations, not the implementation
encapsulation, information-hiding, separation of
interface and implementation.
The Java Collections API
• The Java Collections API provides the following
data structures:
Outline
• (Almost) all data structure implementations in the
Collections API implement the
Collectioninterface.
• It defines, among others, the following methods:
The Collection interface
• Additionally, the
Collectioninterface specifies
the following methods, all of which take another
Collection
as their argument:
The Collection interface (2)
• All Java collections have an
iterator()
method,
which returns an
Iterator
object that steps through
all its elements.
• The
Iterator
object itself provides the following
methods:
• Repeated calls of next() (until hasNext() returns
false) will step through all elements.• remove() can only be called once per call to next().
Iterators
The need for generic programming
void addStuffToCollection(Collection c) {
c.add(new String("Hello world!")); c.add(new String("Good bye!")); c.add(new Integer(95)); printCollection(c); }
void printCollection(Collection c) {
Iterator i = c.iterator(); while(i.hasNext()) {
String item = (String) i.next(); System.out.println("Item: "+item); }
}
• Before Java 5.0, there was no way of keeping track of what types of elements a collection contains.
• Thus, we had to cast variables all over the place. This is both: – Cumbersome: casting when we shouldn’t have to, and – Error-prone: can cause run-time exceptions.
• Generics are a way of restricting the type of elements a collection can contain.
• Collections are now generic classes that take type parameters.
• We can define our own generic types, classes, and methods.
Restricting collection element types
List<MyType> myList = new ArrayList<MyType>(); Instantiating generic classes with type parameters
The need for generic programming, pt.2
void addStuffToCollection(Collection<String> c) {
c.add(new String("Hello world!")); c.add(new String("Good bye!")); c.add(new Integer(95)); printCollection(c); }
void printCollection(Collection<String> c) {
Iterator i = c.iterator(); while(i.hasNext()) {
String item = i.next();
System.out.println("Item: "+item); }
}
What’s wrong with this code?
• The Listinterface represents the list data structure. • Behaviour of standard Collection methods:
• Adds methods for positional/indexed access:
• Like Java arrays, the first element starts from 0. • There are two implementing classes: ArrayList and
LinkedList.
• Remember, you can’t instantiate an interface!
List
Example usage of List
import java.util.ArrayList; import java.util.List; public class ListTester {
public static void main(String[] args) {
List<String> myList = new ArrayList<String>(); for(int ii=0; ii<args.length; ii++)
myList.add(0,args[ii]); while(!myList.isEmpty()) {
String myString = myList.remove(0); System.out.println(myString); }
} }
ListTester program
• An
ArrayListinternally stores items as an array:
• When instantiated, it allocates a contiguous block
of memory. When full, it increases capacity by
allocating a new, larger block (double the size?)
• When inserting/deleting items in the middle,
items must be shifted to the right/left
O(N)
• Accessing items in the middle (by index) is very
fast as we know exactly where it is in memory
O(1)
Implementation 1: ArrayList
• LinkedList
stores items non-contiguously as nodes that
contain reference to the next node in the list.
• Maintains a reference to the beginning of the list (initially
set to
null).• As items are added, it allocates memory
non-contiguously.
• Inserting/deleting items in the middle does not require
any shifting, just updating of next references
O(1)
• Accessing items in the middle (by index) requires
counting from the beginning of the list
O(n)
Implementation 2: LinkedList
Accessing items by index is not efficient with LinkedLists, whereas inserting/removing items in the middle is not efficient with ArrayLists.
Tradeoff between ArrayList and LinkedList
• The Stack class represents the stack data structure. • Behaviour of standard Collectionmethods:
• Provides, among others, the following methods:
• In practice, the Stack class is implemented as a subclass of Vector, an old data structure that is a kind of list.
• All the above operations are O(1).
Stack
Example usage of Stack
import java.util.Stack; public class StackTester {
public static void main(String[] args) {
Stack<String> myStack = new Stack<String>(); for(int ii=0; ii<args.length; ii++)
myStack.push(args[ii]); while(!myStack.isEmpty()) {
String myString = myStack.pop(); System.out.println(myString); }
} }
StackTester program
What is the output of
• The Queue interface represents the queue data structure. • Behaviour of standard Collectionmethods:
• Provides, among others, the following methods:
• Note that Queueis an interface. What classes implement it? Lots! Among others: PriorityQueueand LinkedList! (How is that possible?)
• All the above operations are O(1).
Queues
Example usage of Queue
import java.util.LinkedList; import java.util.Queue; public class QueueTester {
public static void main(String[] args) {
Queue<String> myQ = new LinkedList<String>(); for(int ii=0; ii<args.length; ii++)
myQ.offer(args[ii]); while(!myQ.isEmpty()) {
String myString = myQ.remove(); System.out.println(myString); }
} }
QueueTester program
What is the output of
java QueueTester this is a funny little test?
• The Setinterface represents the set data structure. • Does not provide any new methods, but alters behaviour of
standard Collectionmethods:
• Thus, elements of a Set should make sure equals “makes sense”. • The Setinterface is implemented by the HashSet class. • Requires elements that override a special hashCodemethod. • On average, HashSetoperations are O(1).
Sets
A Set contains no pair of elements e1 and e2 such that e1.equals(e2).
Duplicates are found using Object’s equals method:
• Must override public boolean equals(Object x) (not overload!)
• Must override public int hashCode()
• Think of hashCode as giving a “hint” to HashSet where to store an element.
• Thus, elements of a Set should make sure equals “makes • sense”.
• The Setinterface is implemented by the HashSetclass. • Requires elements that override a special hashCodemethod. • On average, HashSet operations are O(1).
Overriding
equals
and
hashCode
If x.equals(y), then you must ensure that x.hashCode() = y.hashCode() If !x.equals(y), then you should ensure that x.hashCode() 6= y.hashCode()
• What would make a good definition of equals? • What would make a good definition of hashCode?
More on
equals
and
hashCode
Class StudentData {
String studentID, firstName, lastName, address; public boolean equals(Object x)
{
if (x == null || x.getClass() != getClass()) return false;
return studentID.equals(((StudentData)x).studentID); }
public int hashCode() {
return Integer.parseInt(studentID); //?? return firstName.length() + lastName.length() + address.length(); //??
} }
Example of a simple class
Example usage of
Set
import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class SetTester {
public static void main(String[] args) {
Set<String> mySet = new HashSet<String>(); for(int ii=0; ii<args.length; ii++) mySet.add(args[ii]);
Iterator<String> myIterator = mySet.iterator(); while(myIterator.hasNext())
System.out.println(myIterator.next()); }
}
SetTester program
What is the output of
java SetTester this is a very very very funny test?
• The Setinterface has a subinterface, SortedSet, which maintains its items in sorted order.
• Its Iteratoris guaranteed to step through its items in its sorted order.
• Provides the following additional methods, among others:
Sorted Sets
• Elements must be Comparable, i.e. must implement public int compareTo(E x).
• Thus, elements of a Set should make sure equals and compareTo are consistent.
• The SortedSet interface is implemented by the TreeSet class. • On average, TreeSet operations are O(logN), but worst case is
O(N).
SortedSets
and Comparable
A Set contains no pair of elements e1 and e2 such that e1.compareTo(e2)==0.
Example usage of
SortedSet
import java.util.Iterator; import java.util.SortedSet; import java.util.TreeSet; public class SortedSetTester {
public static void main(String[] args) {
SortedSet<String> mySortedSet = new TreeSet<String>();
for(int ii=0; ii<args.length; ii++) mySortedSet.add(args[ii]);
Iterator<String> myIterator = mySortedSet.iterator(); while(myIterator.hasNext())
System.out.println(myIterator.next()); }
}
SortedSetTester program
What is the output of
java SortedSetTester this is a very very very funny test?
• The Map interface defines the map data structure. It is not a Collection!
• Provides the following methods, among others:
Maps
• The Java Collections API provides ready-made
implementations of the various data structures
we have seen.
• Most of the data structures implement the
Collection