Made our linked list generic:
Declare class with a type, T:
public class GenericList<T> {
...
}
Inside the class, T can be used like a variable representing the type:
// add an item of type T
public void add (T item) {
...
}
// get next item of type T
public T next () {
...
}
Now we can use the same GenericList to store any type of object:
GenericList<Animal> zoo = new GenericList<Animal>();
GenericList<Person> school = new GenericList<Person>();
GenericList<Integer> numbers = new GenericList<Integer>();
...
We also implemented methods for iteration:
hasNext() returns true if there is another element in the listnext() returns the next element in the listTo access all the elements in the list:
while (zoo.hasNext()) {
Animal a = zoo.next();
...
}
public void add (T item) {
Node nd = new Node(item);
if (tail != null) {
tail.setNext(nd);
tail = nd;
} else {
head = nd;
tail = nd;
iter = nd;
}
}
When we call list.add(item), the item is added to the end of the list
Consider
GenericList<Integer> list = new GenericList<Integer>();
list.add(4);
list.add(2);
list.add(3);
while (list.hasNext()) {
System.out.println(list.next());
}
What does it print?
Suppose we wanted to store/print elements in sorted order:
SomeList<Integer> list = new SomeList<Integer>();
list.insert(4);
list.insert(2);
list.insert(3);
while (list.hasNext()) {
System.out.println(list.next());
}
We want to see output:
2
3
4
How might we accomplish this?


Use procedure similar to remove method:
prev and curr nodescurr value is at least 5
prev value is smaller than 5
5 between prev and curr




Special cases:
head
tail
public void insert (T item) {
Node nd = new Node(item);
// check if empty
if (tail == null) {
head = nd; tail = nd; iter = nd;
return;
}
// check if insert at head
if (item <= head.item) {
nd.next = head; head = nd; iter = nd;
return;
}
Node prev = head;
Node curr = prev.next;
// find location to insert item: prev.item < item <= curr.item
while (curr != null && item > curr.item) {
prev = curr;
curr = curr.next;
}
// check if tail insert
if (curr == null) {
prev.next = nd; tail = nd;
return;
}
prev.next = nd;
nd.next = curr;
}
public void insert (T item) {
Node nd = new Node(item);
if (tail == null) {
head = nd; tail = nd; iter = nd;
return;
}
if (item <= head.item) {
nd.next = head; head = nd; iter = nd;
return;
}
Node prev = head;
Node curr = prev.next;
while (curr != null && item > curr.item) {
prev = curr;
curr = curr.next;
}
if (curr == null) {
prev.next = nd; tail = nd;
return;
}
prev.next = nd;
nd.next = curr;
}
In order to store a sorted collection, must be able to compare pairs of elements.
Strings alphabeticallyAnimals by…
It doesn’t make sense to compare everything!
Goals:
class supports comparisonSortedList
A way of specifying what a class can/must do
Comparable InterfaceJava defines the Comparable<T> interface:
For a class to be Comparable it must have a method
public int compareTo(T o)If a and b are Comparable objects:
a.compareTo(b) is less than 0, then a is “smaller than” b
a.compareTo(b) is greater than 0, then a is “larger than” b
a.compareTo(b) is 0 then they are treated as equalComparable
Integer, Double, …
String
Animals ComparableTo implement an interface, must:
public class Animal implements Comparable<Animal> {
...
}
public class Animal implements Comparable<Animal> {
...
public int compareTo(Animal a) { ... }
}
How should we compare two Animals?
Create a new class SortedList
GenericList
Comparable
A new declaration:
// T a generic type, but must implement the Comparable<T>
// interface
public class SortedList<T extends Comparable<T>> {
...
}
SortedList
An interface is a contract:
interface, you must provide certain functionalitySorting example:
Comparable
class determines what is meant by comparisonSeparate interface from implementation