Head First Java Chapter 16 — Collection and Generics: Data Structures

Nimesh Mendis
5 min readJul 12, 2022

--

Hello readers,

This article is to highlight the main points include in the chapter.

A collection is a framework in Java that offers an architecture for holding and managing a collection of items. All data operations, including searching, sorting, insertion, modification, and deletion, may be carried out via Java Collections.

A Java Collection is a collection of objects as a single entity. There are several classes and interfaces (Set, List, Queue, and Deque) included in the Java Collection framework (ArrayList, Vector, LinkedList, PriorityQueue, HashSet, LinkedHashSet, TreeSet).

Although ArrayList is the one you’ll use most often, there are others for special occasions.

Collections.sort()

The java.util.Collections class has the function Collections.sort(). We may sort the items in the given Collections list using the Collections.sort() function. The default sorting order for items in Sort() is ascending.

Source: Java point

Generics

Java Generics programming is introduced in J2SE 5 to work with type-safe objects. By identifying errors during the compilation process, it increases code stability. Prior to generic objects, or non-generic objects, we are free to store any kind of item in the collection. Java programmers are now required to keep only one kind of object due to generics.

  • Generics means more type-safety.
  • With generics, you can create type-safe collections where more problems are caught at compile-time instead of runtime.
  • Without generics, the compiler would happily let you put a Pumpkin into an ArrayList that was supposed to hold only Cat Objects.
  • Three things are of importance while dealing with generics.
  • Create instances of generified classes (like ArrayList)

new ArrayList<Song>();

  • Declaring and assigning variables of generic types.

List<Song> songList = new ArrayList<Song>();

  • Declaring (and invoking) methods that take generic types.

void foo(List<Song> list);
x.foo(songList);

Generic Method

Like the generic class, we may develop a generic method that takes any kind of input. In this situation, the scope of the parameters is constrained to the method in which they are defined. Both static and non-static techniques are supported.

  • This one where <T extends Animal> is part of the method declaration, means that any ArrayList declared of a type that is Animal, or one of Animal’s sub type is legal.
    AND

public void takeThing(ArrayList<Animal> list);

  • This method argument means that only an ArrayList<Animal> is legal and not sub type.
  • If you declare a method to take ArrayList<Animal> it can only take an ArrayList<Animal>, not ArrayList<Dog>.
  • Array types are checked again at runtime, but collection type checks happens only when you compile.

Generic Classes

Since ArrayList is our most-used generified type, we’ll start by looking at its documentation. The two key areas to look at in a generified class are:

  1. The class declaration
  2. The method declarations that let you add elements

Generic Implements and Extends

In generics, the keyword “extends” really means “is-a”, and works for BOTH classes and interfaces.

Difference between Comparable and Comparator

Source: Java point

We need a Set instead of List

From the Collection API, we find three main interfaces, List, Set, and Map. ArrayList is a List, but it looks like Set is exactly what we need.

LIST — when sequence matters

Collections that know about index position.
Lists know where something is in the list. You can have more than one element referencing the same object.

SET — when uniqueness matters

Collections that do not allow duplicates.
Sets know whether something is already in the collection. You can never have more than one element referencing the same object (or more than one element referencing two objects that are considered equal — we’ll look at what object equality means in a moment).

MAP — when finding something by key matters

Collections that use key-value pairs.
Maps know the value associated with a given key. You can have two keys that reference the same value, but you cannot have duplicate keys. Although keys are typically String names (so that you can make name/value property lists, for example), a key can be any object.

Source: Java point

The Collections API

HashSet

  • A HashSet checks the hasCodes, if they are different the object are assumed to be different.

TreeSet

  • A TreeSet is similar to HashSet in that it prevents duplicates, and it also keeps the list sorted.
  • To use a TreeSet, one of these things must be true.
  • The element in the list must be of a type that implements Comparable.
    OR
  • You use the TreeSet’s overloaded constructor that takes a Comparator.

Map

  • Each element in a Map is actually TWO Objects — a key and a value. You can have duplicate values, but NOT Duplicate keys

LinkedList

  • Makes it easy to create structures like stacks or queues.

LinkedHashMap

  • Like a regular HashMap, except it can remember the order in which elements (name/value pairs) were inserted, or it can be configured to remember the order in which elements were last accessed.

Generic WildCards

  • There is a way a method argument that can accept an ArrayList of any Animal sub type.

public void takeAnimal(ArrayList <? extends Animal> animals){
for
(Animal animal : animals) {
animal.eat();
}
}

OR

public <T extends Animal>void takeAnimal(ArrayList <T> animals){
for
(Animal animal : animals) {
animal.eat();
}
}

  • When you use a wild card in you method argument, the compiler will STOP you from doing anything that could hurt the list referenced by the method parameters.
  • You can still invoke methods on the elements in the list, but you cannot add elements to the list.
  • In other words, you can do things with the list elements, but you cannot put new things in the list.

--

--