Generic types allow more flexible type constraints in classes and methods, while still providing more type safety than casting everything to Object. Collections are a collection (heh :) ) of classes to allow aggregation of objects in lists, maps, and other groupings.
Oracle Java Tutorial links
- Create a generic class.
- Use the diamond syntax to create a collection.
- Analyze the interoperability of collections that use raw types and generic types.
- Use wrapper classes and autoboxing.
- Create and use a List, a Set, and a Deque.
- Create and use a Map.
- Use java.util.Comparator and java.lang.Comparable.
- Sort and search arrays and lists.
Do the exercises for Generics in the Oracle Java tutorial here. Once you are done, the answers can be checked here.
Do the exercises for Collection Interfaces in the Oracle Java tutorial here. Once you are done, the answers can be checked here.
Do the exercises for Collection Implementations in the Oracle Java tutorial here. Once you are done, the answers can be checked here.

Lets start by creating the class StringTree in package generics. This class is used to construct a tree of Strings, each node in the tree holding a single String value.
The constructor of StringTree should take a single String value for that tree node. The class should also have the method addChild(StringTree child).
The depth of a node in a tree is how far away from the current node it is, with a depth of 0 being the current node. Create a method getAllValues(int depth), which returns a list of tree values at the specified depth. For example, from the root node of the tree shown here would return {"8"} for getAllValues(0), {"3", "10"} for getAllValues(1), and {"1", "6", "14"} for getAllValues(2).
Override the toString method to return the current node value and the toString results of all the child nodes. For example, calling toString on the node "3" in the figure should return:
'3' => ['1' => [], '6' => ['4' => [], '7' => []]]
In summary, create the following methods for the class:
public class StringTree { public StringTree(String value) { ... } public void addChild(StringTree child) { ... } public List<String> getAllValues(int depth) { ... } @Override public String toString() { ... } }
An automated test has been created for this exercise: StringTreeTest.java (in package generics).
StringTree is fine for Strings. Lets make use of generics. Create a generic class Tree in the same package, which accepts the generic type parameter of the value of each tree node, so Tree<String> would be a tree of Strings as before, and Tree<Integer> would be a tree of Integers. Modify the methods described above to make use of the type parameter.
An automated test has been created for this exercise: GenericTreeTest.java (in package generics).