Java Collection Interface

Since Java 1.2, we have Java Collections API to represent and manipulate collections in Java in a standard way. There are two "root" interfaces: java.util.Collection and java.util.Map. In this article, we will run through the first interface: Collection.

There is no direct implementation of Collection interface, but there are classes that implemented through Collection sub-interfaces like List, Queue, and Set. For example:

  • ArrayList implements List
  • PriorityQueue implements Queue
  • HashSet implements Set

Check below diagram for the classes and the "Collection" interfaces they are implemented.

Collection
<interface>
List
<interface>
ArrayList
VectorStack
LinkedList
Queue
<interface>
Deque
<interface>
PriorityQueue
Set
<interface>
HashSet
LinkedHashSet
SortedSet
<interface>
NavigableSet
<interface>
TreeSet

For your notes, the Collection classes are extended from AbstractCollection class that not in our table above. Here the structure:

  • AbstractCollection implements Collection
  • AbstractList implements List extends AbstractCollection
  • AbstractQueue implements Queue extends AbstractCollection
  • AbstractSet implements Set extends AbstractCollection
  • ArrayList, Vector, and AbstractSequentialList extends AbstractList
  • LinkedList implements Deque and extends AbstractSequentialList
  • PriorityQueue extends AbstractQueue
  • TreeSet implemets NavigableSet extends AbstractSet

To understand fully the structure, you need to understand about Inheritance in Java.

As mentioned above, you cannot create a Collection instance directly, but an instance of one of the sub-types of Collection. Here some samples to create Collection based on different sub-types:

Collection colAL = new ArrayList(); System.out.println(colAL.getClass().getName()); Collection colV = new Vector(); System.out.println(colV.getClass().getName()); Collection colS = new Stack(); System.out.println(colS.getClass().getName()); Collection colLL = new LinkedList(); System.out.println(colLL.getClass().getName()); Collection colPQ = new PriorityQueue(); System.out.println(colPQ.getClass().getName()); Collection colHS = new HashSet(); System.out.println(colHS.getClass().getName()); Collection colLHS = new LinkedHashSet(); System.out.println(colLHS.getClass().getName()); Collection colTS = new TreeSet(); System.out.println(colTS.getClass().getName());

Result:

java.util.ArrayList
java.util.Vector
java.util.Stack
java.util.LinkedList
java.util.PriorityQueue
java.util.HashSet
java.util.LinkedHashSet
java.util.TreeSet

For your reference, here the information we can "extract" from a Collection with sub-type LinkedList:

Collection ll = new LinkedList(); System.out.println("Class : " + ll.getClass().getName()); Class[] tis = ll.getClass().getInterfaces(); for (Class ti : tis) { System.out.println("Interface : " + ti.getTypeName()); } System.out.println("is Collection: " + (ll instanceof Collection));

Result:

Class        : java.util.LinkedList
Interface    : java.util.List
Interface    : java.util.Deque
Interface    : java.lang.Cloneable
Interface    : java.io.Serializable
is Collection: true

Add/Remove Element(s) from a Collection

Following methods can be used to add or remove objects from Collection:

The first example is to add element(s) to a Collection using add(...) method:

private void addToCollection(Collection collection) { collection.add("one"); collection.add("two"); collection.add("three"); collection.add("one"); collection.add("two"); collection.add("three"); System.out.println(collection.getClass().getName() + " : " + collection); } ... CollectionInterfaceAddRemove app = new CollectionInterfaceAddRemove(); Collection colAL = new ArrayList(); app.addToCollection(colAL); Collection colV = new Vector(); app.addToCollection(colV); Collection colS = new Stack(); app.addToCollection(colS); Collection colLL = new LinkedList(); app.addToCollection(colLL); Collection colPQ = new PriorityQueue(); app.addToCollection(colPQ); Collection colHS = new HashSet(); app.addToCollection(colHS); Collection colLHS = new LinkedHashSet(); app.addToCollection(colLHS); Collection colTS = new TreeSet(); app.addToCollection(colTS);

Result:

java.util.ArrayList : [one, two, three, one, two, three]
java.util.Vector : [one, two, three, one, two, three]
java.util.Stack : [one, two, three, one, two, three]
java.util.LinkedList : [one, two, three, one, two, three]
java.util.PriorityQueue : [one, one, three, two, two, three]
java.util.HashSet : [one, two, three]
java.util.LinkedHashSet : [one, two, three]
java.util.TreeSet : [one, three, two]

The app here (and the next samples) will refer to CollectionInterfaceAddRemove class.

The elements in PriorityQueue and TreeSet above are ordered by their natural ordering, since no "custom" Comparator is used.

HashSet, LinkedHashSet, and TreeSet implements Set interface which not allowing duplicate elements.

Continue from above example, here the sample to remove an element from a Collection, using remove(...) method:

private void removeFromCollection(Collection collection) { collection.remove("two"); System.out.println(collection.getClass().getName() + " : " + collection); } ... app.removeFromCollection(colAL); app.removeFromCollection(colV); app.removeFromCollection(colS); app.removeFromCollection(colLL); app.removeFromCollection(colPQ); app.removeFromCollection(colHS); app.removeFromCollection(colLHS); app.removeFromCollection(colTS);

With result:

java.util.ArrayList : [one, three, one, two, three]
java.util.Vector : [one, three, one, two, three]
java.util.Stack : [one, three, one, two, three]
java.util.LinkedList : [one, three, one, two, three]
java.util.PriorityQueue : [one, one, three, three, two]
java.util.HashSet : [one, three]
java.util.LinkedHashSet : [one, three]
java.util.TreeSet : [one, three]

Although not captured in my example, remove() method return a boolean value. If the element was present, it returns true, else return false.

Still continue from previous example, here the sample for add elements based on a Collection to a Collection, using addAll(...) method:

private void addAllToCollection(Collection collection) { Collection list = new ArrayList(); list.add("uno"); list.add("due"); list.add("tre"); collection.addAll(list); System.out.println(collection.getClass().getName() + " : " + collection); } ... app.addAllToCollection(colAL); app.addAllToCollection(colV); app.addAllToCollection(colS); app.addAllToCollection(colLL); app.addAllToCollection(colPQ); app.addAllToCollection(colHS); app.addAllToCollection(colLHS); app.addAllToCollection(colTS);

The result are:

java.util.ArrayList : [one, three, one, two, three, uno, due, tre]
java.util.Vector : [one, three, one, two, three, uno, due, tre]
java.util.Stack : [one, three, one, two, three, uno, due, tre]
java.util.LinkedList : [one, three, one, two, three, uno, due, tre]
java.util.PriorityQueue : [due, one, one, three, two, uno, three, tre]
java.util.HashSet : [due, tre, one, uno, three]
java.util.LinkedHashSet : [one, three, uno, due, tre]
java.util.TreeSet : [due, one, three, tre, uno]

From the example above, we know that we can add elements from one Collection to another Collection although it have different sub-type. Variable list which sub-type is an ArrayList, can be added to Stack, PriorityQueue, HashSet, etc. The result is depends on the Collection sub-type, some allowing duplicates, where others not.

And next, we are using removeAll(..) to remove elements from a Collection based on another Collection.

private void removeAllFromCollection(Collection collection) { Collection set = new HashSet(); set.add("one"); set.add("two"); set.add("three"); collection.removeAll(set); System.out.println(collection.getClass().getName() + " : " + collection); } ... app.removeAllFromCollection(colAL); app.removeAllFromCollection(colV); app.removeAllFromCollection(colS); app.removeAllFromCollection(colLL); app.removeAllFromCollection(colPQ); app.removeAllFromCollection(colHS); app.removeAllFromCollection(colLHS); app.removeAllFromCollection(colTS);

Result:

java.util.ArrayList : [uno, due, tre]
java.util.Vector : [uno, due, tre]
java.util.Stack : [uno, due, tre]
java.util.LinkedList : [uno, due, tre]
java.util.PriorityQueue : [due, tre, uno]
java.util.HashSet : [due, tre, uno]
java.util.LinkedHashSet : [uno, due, tre]
java.util.TreeSet : [due, tre, uno]

Opposite of removeAll(...), retainAll(...) keeps only the elements in the Collection that are contained in the parameter Collection. It'll removes other elements that not part of the parameter Collection.

private void retainAllFromCollection(Collection collection) { Collection anotherCol = new PriorityQueue(); anotherCol.add("uno"); anotherCol.add("tre"); anotherCol.add("cinque"); collection.retainAll(anotherCol); System.out.println(collection.getClass().getName() + " : " + collection); } ... app.retainAllFromCollection(colAL); app.retainAllFromCollection(colV); app.retainAllFromCollection(colS); app.retainAllFromCollection(colLL); app.retainAllFromCollection(colPQ); app.retainAllFromCollection(colHS); app.retainAllFromCollection(colLHS); app.retainAllFromCollection(colTS);

Result:

java.util.ArrayList : [uno, tre]
java.util.Vector : [uno, tre]
java.util.Stack : [uno, tre]
java.util.LinkedList : [uno, tre]
java.util.PriorityQueue : [tre, uno]
java.util.HashSet : [tre, uno]
java.util.LinkedHashSet : [uno, tre]
java.util.TreeSet : [tre, uno]

Working with Collection

There are some common methods when working with a Collection

  • boolean contains(Object o): check if this collection contains the specified element.
  • boolean containsAll(Collection<?> c): check if this collection contains the elements in the parameter collection.
  • boolean isEmpty(): check if this collection contains no elements.
  • int size(): get the number of elements in this collection.

Let's check below example for contains(...) and containsAll(...):

Collection list = new LinkedList(); list.add("red"); list.add("green"); list.add("blue"); System.out.println("List : " + list); System.out.println("List contains green?: " + list.contains("green")); Collection set = new TreeSet(); set.add("red"); set.add("green"); System.out.println("Set : " + set); System.out.println("List contains set? : " + list.containsAll(set)); set.add("black"); System.out.println("Set : " + set); System.out.println("List contains set? : " + list.containsAll(set));

The result is:

List                : [red, green, blue]
List contains green?: true
Set                 : [green, red]
List contains set?  : true
Set                 : [black, green, red]
List contains set?  : false

contains(...) returns true since it have green in the collection. containsAll(...) returns true when checking if the collection contains green and red. It returns false in the next checking, because not containing black.

Use size() to check collection's size, and use isEmpty() to check if collection is empty or not.

Collection al = new ArrayList(); System.out.println("ArrayList size : " + al.size() + ", isEmpty?: " + al.isEmpty()); al.addAll(list); System.out.println("Add to ArrayList : " + list); System.out.println("ArrayList size (now): " + al.size() + ", isEmpty?: " + al.isEmpty());

Result:

ArrayList size      : 0, isEmpty?: true
Add to ArrayList    : [red, green, blue]
ArrayList size (now): 3, isEmpty?: false

How to iterate over a Java Collection

There are several ways to iterate through a Collection in Java. The first way, using for each loop:

Collection pq = new PriorityQueue(); pq.addAll(al); System.out.println("Loop PriorityQueue:"); for (Object obj : pq) { System.out.println(obj); }

With result:

Loop PriorityQueue:
blue
red
green

The second is using iterator. We iterate as long as hasNext() is true, and each element is obtained using next() method. To iterate, we can use while or for:

System.out.println("Iterate PriorityQueue using Iterator:"); System.out.println("Using while >>>"); Iterator it1 = pq.iterator(); // while while (it1.hasNext()) { System.out.println(it1.next()); } System.out.println("Using for loop >>>"); // for loop for (Iterator it2 = pq.iterator(); it2.hasNext();) { System.out.println(it2.next()); }

Result:

Iterate PriorityQueue using Iterator:
Using while >>>
blue
red
green
Using for loop >>>
blue
red
green