Aggregate

In the previous chapters, we have discovered the array. An array stores a group of primitive types. To group objects, or to reference a group of objects, we can use Java aggregate classes. There are two main interfaces, those are `java.util.Collection` and `java.util.Map` . Implementations for those interfaces are not interchangeable.

Collection

The implementations of `java.util.Collection` interface are used for grouping simple java objects.

Example
We can group together all patients in a Hospital to a "patient" collection.

Map

The implementations of `java.util.Map` interface are used to represent mapping between "key" and "value" objects. A Map represents a group of "key" objects, where each "key" object is mapped to a "value" object.

Example
For each patient, there is one and only one main nurse assigned to. That association can be represented by a "patient-nurse" Map.

Choice

A collection is better when you have to access all the items at once. A map is better when you have to randomly access an item regularly.

Before selecting a particular collection implementation, ask the following question:

Can my collection contain the same elements, i.e. are duplicates allowed?

Can my collection contain the `null` element?

Should the collection maintain the order of the elements? Is the order important in any way?

How do you want to access an element? By index, key or just with an iterator?

Does the collection need to be synchronized?

From a performance perspective, which one needs to be faster, updates or reads?

From a usage perspective, which operation will be more frequent, updates or reads?

Once you know your needs, you can select an existing implementation. But first decide if you need a `Collection`, or a `Map`.

Note that the above associations are explicit. The objects them-self do not have any knowledge/information about that they are part in an association. But creating explicit associations between simple java objects is the main idea about using the aggregate/collection classes.

Collection

The most basic collection interface is called `Collection`. This interface gives the user the generic usage of a collection. All collections need to have the same basic operations. Those are:

• Adding element(s) to the collection
• Removing element(s) from the collection
• Obtaining the number of elements in the collection
• Listing the contents of the collection, (Iterating through the collection)
 Code listing 5.1: CollectionProgram.java ``` 1 import java.util.Collection; // Interface 2 import java.util.ArrayList; // Implementation 3 4 public class CollectionProgram { 5 6 public static void main(String[] args) { 7 Collection myCollection = new ArrayList(); 8 myCollection.add("1"); 9 myCollection.add("2"); 10 myCollection.add("3"); 11 System.out.println("The collection contains " + myCollection.size() + " item(s)."); 12 13 myCollection.clear(); 14 if (myCollection.isEmpty()) { 15 System.out.println("The collection is empty."); 16 } else { 17 System.out.println("The collection is not empty."); 18 } 19 } 20 } ```
 Console for Code listing 5.1 ```The collection contains 3 item(s). The collection is empty. ```

When you put an object in a collection, this object is not actually in the collection. Only its object reference is added to the collection. This means that if an object is changed after it was put in an collection, the object in the collection also changes. The code listing 5.2 computes the seven next days from tomorrow and stores each date in a list to read it afterwards. See what happens:

 Code listing 5.2: SevenNextDays.java ``` 1 import java.util.ArrayList; 2 import java.util.Calendar; 3 import java.util.Collection; 4 import java.util.Date; 5 import java.util.GregorianCalendar; 6 7 public class SevenNextDays { 8 9 public static void main(String[] args) { 10 11 // The calendar is set at the current date: today 12 Calendar calendar = new GregorianCalendar(); 13 14 Collection collectionOfDays = new ArrayList(); 15 Date currentDate = new Date(); 16 for (int i = 0; i < 7; ++i) { 17 // The calendar is now set to the next day 18 calendar.add(Calendar.DATE, 1); 19 currentDate.setTime(calendar.getTimeInMillis()); 20 21 collectionOfDays.add(currentDate); 22 } 23 24 for (Object oneDay : collectionOfDays) { 25 System.out.println("The next day is: " + oneDay); 26 } 27 } 28 } ```
 Console for Code listing 5.2 ` The next day is: Mon Feb 12 14:18:06 UTC 2018` ` The next day is: Mon Feb 12 14:18:06 UTC 2018` ` The next day is: Mon Feb 12 14:18:06 UTC 2018` ` The next day is: Mon Feb 12 14:18:06 UTC 2018` ` The next day is: Mon Feb 12 14:18:06 UTC 2018` ` The next day is: Mon Feb 12 14:18:06 UTC 2018` ` The next day is: Mon Feb 12 14:18:06 UTC 2018`

All collection items were meant to be updated to a different date but they all have been updated to the last one. This means that each update has updated all the collection items. The `currentDate` has been used to fill all the collection items. The collection didn't keep trace of the added values (one of the seven dates) but the added object references (`currentDate`). So the collection contains the same object seven times! To avoid this issue, we should have coded it this way:

 Code listing 5.3: ActualSevenNextDays.java ``` 1 import java.util.ArrayList; 2 import java.util.Calendar; 3 import java.util.Collection; 4 import java.util.Date; 5 import java.util.GregorianCalendar; 6 7 public class ActualSevenNextDays { 8 9 public static void main(String[] args) { 10 11 // The calendar is set at the current date: today 12 Calendar calendar = new GregorianCalendar(); 13 14 Collection collectionOfDays = new ArrayList(); 15 for (int i = 0; i < 7; ++i) { 16 Date currentDate = new Date(); 17 // The calendar is now set to the next day 18 calendar.add(Calendar.DATE, 1); 19 currentDate.setTime(calendar.getTimeInMillis()); 20 21 collectionOfDays.add(currentDate); 22 } 23 24 for (Object oneDay : collectionOfDays) { 25 System.out.println("The next day is: " + oneDay); 26 } 27 } 28 } ```
 Console for Code listing 5.3 ` The next day is: Tue Feb 6 14:18:06 UTC 2018` ` The next day is: Wed Feb 7 14:18:06 UTC 2018` ` The next day is: Thu Feb 8 14:18:06 UTC 2018` ` The next day is: Fri Feb 9 14:18:06 UTC 2018` ` The next day is: Sat Feb 10 14:18:06 UTC 2018` ` The next day is: Sun Feb 11 14:18:06 UTC 2018` ` The next day is: Mon Feb 12 14:18:06 UTC 2018`

Now each time we add an item to the collection, it is a different instance. All the items evolve separately. To add an object in a collection and avoid this item being changed each time the source object is changed, you have to copy or clone the object before you add it to the collection.

Generics

Objects put into a collection are upcasted to the `Object` class. This means that you need to cast the object reference back when you get an element out of the collection. It also means that you need to know the type of the object when you take it out. If a collection contains different types of objects, we will have difficulty finding out the type of the objects obtained from a collection at run time. For example. let's use this collection with two objects in it:

 Code section 5.1: Collection feeding. ```1 Collection ageList = new ArrayList(); 2 ageList.add(new Integer(46)); 3 ageList.add("50"); ```
 Code section 5.2: Collection reading. ```1 Integer sum = new Integer(0); 2 for (Object age : ageList) { 3 sum = sum.add((Integer) age); 4 } 5 6 if (!ageList.isEmpty()) { 7 System.out.println("The average age is " + sum / ageList.size()); 8 } ```
 Console for Code section 5.2 ```ClassCastException. ```

This error could have been found earlier, at compile time, by using generic types. The Generics have been added since JDK version 1.5. It is an enhancement to the type system of the Java language. All collection implementations since 1.5 now have a parameterized type <E>. The E refers to an Element type. When a collection is created, the actual Element type will replace the E. In the collection, the objects are now upcasted to E class.

 Code section 5.3: Collection with generics. ```1 Collection ageList = new ArrayList(); 2 ageList.add(new Integer(46)); // Integer can be added 3 ageList.add("50"); // Compilation error, ageList can have only Integers inside ```

`ageList` is a collection that can contain only Integer objects as elements. No casting is required when we take out an element.

 Code section 5.4: Item reading. ```1 Integer age = ageList.get(0); ```

Generics are not mandatory but are is often used with the collection classes.

Collection classes

There is no direct implementation for the `java.util.Collection` interface. The Collection interface has five sub interfaces.

 Figure 1: The five sub interfaces of the `java.util.Collection` interface.

Set

A set collection contains unique elements, so duplicates are not allowed. It is similar to a mathematical Set. When adding a new item to a set, the set calls the method `int hashCode()` of the item and compares its result to the hash code of all the already inserted items. If the hash code is not found, the item is added. If the hash code is found, the set calls the `boolean equals(Object obj);` method for all the set items with the same hashcode as the new item. If all equal-calls return false, the new item is inserted in the set. If an equal-call returns true, the new item is not inserted in the set.

 Figure 2: Set class diagram.

java.util.HashSet<E>
This is the basic implementation of the `Set` interface. Not synchronized. Allows the `null` elements
java.util.TreeSet<E>
Elements are sorted, not synchronized. `null` not allowed
java.util.CopyOnWriteArraySet<E>
Thread safe, a fresh copy is created during modification operation. Add, update, delete are expensive.
java.util.EnumSet<E extends Enum<E>>
All of the elements in an enum set must come from a single enum type that is specified, explicitly or implicitly, when the set is created. Enum sets are represented internally as bit vectors.
Same as HashSet, plus defines the iteration ordering, which is the order in which elements were inserted into the set.

Detecting duplicate objects in Sets

`Set` cannot have duplicates in it. You may wonder how duplicates are detected when we are adding an object to the `Set`. We have to see if that object exists in the Set or not. It is not enough to check the object references, the objects' values have to be checked as well.

To do that, fortunately, each java object has the `boolean equals(Object obj)`, method available inherited from `Object`. You need to override it. That method will be called by the Set implementation to compare the two objects to see if they are equal or not.

There is a problem, though. What if I put two different type of objects to the Set. I put an Apple and an Orange. They can not be compared. Calling the `equals()` method would cause a `ClassCastException`. There are two solutions to this:

• Solution one : Override the `int hashCode()` method and return the same values for the same type of objects and return different values for different type of objects. The `equals()` method is used to compare objects only with the same value of hashCode. So before an object is added, the Set implementation needs to:
• find all the objects in the Set that have the same hashCode as the candidate object hashCode
• and for those, call the `equals()` methods passing in the candidate object
• if any of them returns true, the object is not added to the Set.
• Solution two : Create a super class for the Apple and Orange, let's call it Fruit class. Put Fruits in the Set. You need to do the following:
• Do not override the `equals()` and `hashCode()` methods in the Apple and Orange classes
• Create `appleEquals()` method in the Apple class, and create `orangeEquals()` method in the Orange class
• Override the `hashCode()` method in the Fruit class and return the same value, so the `equals()` is called by the Set implementation
• Override the `equals()` method in the Fruit class for something like this.
 Code section 5.5: `equals` method implementation. ``` 1 public boolean equals(Object obj) { 2 boolean ret = false; 3 if (this instanceof Apple && 4 obj instanceof Apple) { 5 ret = this.appleEquals(obj); 6 } else if (this instanceof Orange && 7 obj instanceof Orange) { 8 ret = this.orangeEquals(obj); 9 } else { 10 // Can not compare Orange to Apple 11 ret = false; 12 } 13 return ret; 14 } ```

Note:

• Only the objects that have the same hashCode will be compared.
• You are responsible to override the `equals()` and `hashCode()` methods. The default implementations in Object won't work.
• Only override the `hashCode()` method if you want to eliminate value duplicates.
• Do not override the `hashCode()` method if you know that the values of your objects are different, or if you only want to prevent adding the exactly same object.
• Beware that the `hashCode()` may be used in other collection implementations, like in a Hashtable to find an object fast. Overriding the default `hashCode()` method may affect performance there.
• The default hashCodes are unique for each object created, so if you decide not to override the `hashCode()` method, there is no point overriding the `equals()` method, as it won't be called.

SortedSet

The `SortedSet` interface is the same as the Set interface plus the elements in the SortedSet are sorted. It extends the Set Interface. All elements in the SortedSet must implement the Comparable Interface, furthermore all elements must be mutually comparable.

Note that the ordering maintained by a sorted set must be consistent with equals if the sorted set is to correctly implement the Set interface. This is so because the Set interface is defined in terms of the equals operation, but a sorted set performs all element comparisons using its compare method, so two elements that are deemed equal by this method are, from the standpoint of the sorted set, equal.

The SortedSet interface has additional methods due to the sorted nature of the 'Set'. Those are:

 `E first();` returns the first element `E last();` returns the last element `SortedSet headSet(E toElement);` returns from the first, to the exclusive toElement `SortedSet tailSet(E fromElement);` returns from the inclusive fromElement to the end `SortedSet subSet(E fromElement, E toElement);` returns elements range from fromElement, inclusive, to toElement, exclusive. (If fromElement and toElement are equal, the returned sorted set is empty.)

List

In a list collection, the elements are put in a certain order, and can be accessed by an index. Duplicates are allowed, the same element can be added twice to a list. It has the following implementations:

 Figure 3: List class diagram.

java.util.Vector<E>
Synchronized, use in multiple thread access, otherwise use ArrayList.
java.util.Stack<E>
It extends class Vector with five operations that allow a vector to be treated as a stack. It represents a last-in-first-out (LIFO) stack of objects.
java.util.ArrayList<E>
The basic implementation of the `List` interface is the `ArrayList`. The ArrayList is not synchronized, not thread safe. `Vector` is synchronized, and thread safe. `Vector` is slower, because of the extra overhead to make it thread safe. When only one thread is accessing the list, use the ArrayList. Whenever you insert or remove an element from the list, there are extra overhead to reindex the list. When you have a large list, and you have lots of insert and remove, consider using the `LinkedList`.
Non-synchronized, update operation is faster than other lists, easy to use for stacks, queues, double-ended queues. The name `LinkedList` implies a special data structure where the elements/nodes are connected by pointers.
``` Head               Node 1                   Node 2                     Node n
______
| Size |          _________________        _______________            _____________
|______|         |      | point   |       |      | point  |          |      |      |
| First|-------->| Data | to next |------>| Data | to next|-- ... -->| Data | null |
| elem |         |______|_________|       |______|________|          |______|______|
|______|                                                                 ^
| Last |                                                                 |
| elem |-----------------------------------------------------------------
|______|
```

Each node is related to an item of the linked list. To remove an element from the linked list the pointers need to be rearranged. After removing Node 2:

``` Head               Node 1                   Node 2                     Node n
______                                 _____________________
| Size |          _________________    |   _______________   |       ______________
|_- 1__|         |      | point   |    |  |      | point  |  |       |      |      |
| First|-------->| Data | to next |----   | Data | to next|   -...-->| Data | null |
| elem |         |______|_________|       |______|________|          |______|______|
|______|                                                                 ^
| Last |                                                                 |
| elem |-----------------------------------------------------------------
|______|
```
javax.management.AtributeList<E>
Represents a list of values for attributes of an MBean. The methods used for the insertion of Attribute objects in the AttributeList overrides the corresponding methods in the superclass ArrayList. This is needed in order to insure that the objects contained in the AttributeList are only Attribute objects.
javax.management.relation.RoleList<E>
A RoleList represents a list of roles (Role objects). It is used as parameter when creating a relation, and when trying to set several roles in a relation (via 'setRoles()' method). It is returned as part of a RoleResult, to provide roles successfully retrieved.
javax.management.relation.RoleUnresolvedList<E>
A RoleUnresolvedList represents a list of RoleUnresolved objects, representing roles not retrieved from a relation due to a problem encountered when trying to access (read or write to roles).

Queue

The Queue interface provides additional insertion, extraction, and inspection operations. There are FIFO (first in, first out) and LIFO (last in, first out) queues. This interface adds the following operations to the Collection interface:

 `E element()` Retrieves, but does not remove, the head of this queue. This method differs from the peek method only in that it throws an exception if this queue is empty `boolean offer(E o)` Inserts the specified element into this queue, if possible. `E peek()` Retrieves, but does not remove, the head of this queue, returning null if this queue is empty `E poll()` Retrieves and removes the head of this queue, or null if this queue is empty `E remove()` Retrieves and removes the head of this queue. This method differs from the poll method in that it throws an exception if this queue is empty.
 Figure 4: Queue class diagram.

java.util.BlockingQueue<E>
waits for the queue to become non-empty when retrieving an element, and waits for space to become available in the queue when storing an element. Best used for producer-consumer queues.
java.util.PriorityQueue<E>
orders elements according to an order/priority specified at construction time, null element is not allowed.
java.util.concurrent.ArrayBlockingQueue<E>
orders elements FIFO; synchronized, thread safe.
java.util.concurrent.SynchronousQueue<E>
each put must wait for a take, and vice versa, does not have any internal capacity, not even a capacity of one, an element is only present when you try to take it; you cannot add an element (using any method) unless another thread is trying to remove it.

Complete UML class diagram

 Figure 5: UML class diagram of the `Collection` interfaces and their implementations.

Synchronization

Synchronization is important when you are running several threads. Beware, synchronization does not mean that your collection is thread-safe. A thread-safe collection is also called a concurrent collection. Most of the popular collection classes have implementations for both single thread and multiple thread environments. The non-synchronized implementations are always faster. You can use the non-synchronized implementations in multiple thread environments, when you make sure that only one thread updates the collection at any given time.

A new Java JDK package was introduced at Java 1.5, that is `java.util.concurrent`. This package supplies a few Collection implementations designed for use in multi-threaded environments.

The following table lists all the synchronized collection classes:

 synchronized non-synchronized List java.util.Vector java.util.ArrayList java.util.Stack java.util.LinkedList java.util.concurrent.CopyOnWriteArrayList Set java.util.TreeSet java.util.HashSet java.util.LinkHashSet java.util.concurrent.CopyOnWriteArraySet

Custom collection

The Java JDK collection implementations are quite powerful and good, so it is unlikely that you will need to write your own. The usage of the different collections are the same but the implementations are different. If the existing collection implementations do not meet your needs, you can write your version of the implementation. Your version of the implementation just needs to implement the same `java.util.Collection` interface, then you can switch to using your implementation and the code that is using the collection does not need to be changed.

Use the Collection interface if you need to keep related (usually the same type of) objects together in a collection where you can:

• Search for a particular element
• List the elements
• Maintain and/or change the order of the elements by using the collection basic operations (Add, Remove, Update,..)
• Access the elements by an index number

The advantages of using the `Collection` interface are:

• Gives a generic usage, as we talked about above, it is easy to switch implementation
• It makes it easy to convert one type of collection to another.

The `Collection` interface defines the following basic operations:

 `boolean add(E o);` Using Element type E `boolean addAll(Collection c);` `boolean remove(`Object o); `boolean removeAll(Collection c);` `boolean retainAll(Collection c);` Return `true` if the collection has changed due to the operation.

Note that in `addAll()` we can add any type of collection. This is the beauty of using the Collection interface. You can have a `LinkedList` and just call the `addAll(list)` method, passing in a list. You can pass in a `Vector`, an `ArrayList`, a `HashSet`, a `TreeSet`, a `YourImpOfCollection`, ... All those different types of collection will be magically converted to a `LinkedList`.

Let's have a closer look at this magic. The conversion is easy because the `Collection` interface defines a standard way of looping through the elements. The following code is a possible implementation of `addAll()` method of the `LinkedList`.

 Code section 5.6: Collection transfer. ``` 1 import java.util.Collection 2 import java.util.Iterator 3 ... 4 public boolean addAll(Collection coll) { 5 int sizeBefore = this.size(); 6 Iterator iter = coll.iterator(); 7 while(iter.hasNext()) { 8 this.add(iter.next()); 9 } 10 if (sizeBefore > this.size()) { 11 return true; 12 } else { 13 return false; 14 } 15 } ```

The above code just iterates through the passed in collection and adds the elements to the linked list. You do not have to do that, since that is already defined. What you might need to code for is to loop through a `Customer` collection:

 Code section 5.7: Iteration on a collection. ``` 1 import java.util.Collection 2 import java.util.Iterator 3 import java.yourcompany.Customer 4 ... 5 public String printCustomerNames(Collection customerColl) { 6 StringBuffer buf = new StringBuffer(); 7 8 Iterator iter = customerColl.iterator(); 9 while(iter.hasNext()) { 10 Customer cust = (Customer) iter.next(); 11 buf.append(cust.getName()); 12 buf.append( "\n" ); 13 } 14 return buf.toString(); 15 } ```

Notice two things:

• The above code will work for all type of collections.
• We have to know the type of objects inside the collection, because we call a method on it.

ArrayList

The ArrayList class extends AbstractList and implements the List interface. ArrayList supports dynamic arrays that can grow as needed.

Standard Java arrays are of a fixed length. After arrays are created, they cannot grow or shrink, which means that you must know in advance how many elements an array will hold.

Array lists are created with an initial size. When this size is exceeded, the collection is automatically enlarged. When objects are removed, the array may be shrunk.

Initializing

The ArrayList class supports three constructors. The first constructor builds an empty array list.:

```ArrayList( )
```

The following constructor builds an array list that is initialized with the elements of the collection c.

```ArrayList(Collection c)
```

The following constructor builds an array list that has the specified initial capacity. The capacity is the size of the underlying array that is used to store the elements.

The capacity grows automatically as elements are added to an array list.

``` ArrayList(int capacity)
```

Methods

ArrayList defines following methods:

• Inserts the specified element at the specified position index in this list. Throws IndexOutOfBoundsException if the specified index is out of range (index < 0 || index >= size()).
```void add(int index, Object element)
```
• Appends the specified element to the end of this list.
```boolean add(Object o)
```
• Appends all of the elements in the specified collection to the end of this list, in the order that they are returned by the specified collection's iterator. Throws NullPointerException if the specified collection is null.
```boolean addAll(Collection c)
```
• Inserts all of the elements in the specified collection into this list, starting at the specified position. Throws NullPointerException if the specified collection is null.
```boolean addAll(int index, Collection c)
```

Size of ArrayList

• Returns the number of elements in this list.
```int size()
```

Adding Element and Size of ArrayList

```
import java.util.*;

public class ArrayListDemo{
public static void main(String[] args) {
// create an array list
ArrayList al= new ArrayList();
System.out.println("Initial ArrayList : "+al);

// add elements to the array list

//find size of ArrayList
System.out.println("Size of al :"+al.size());
// display the array list
System.out.println("Contents of al :"+al);
System.out.println("Contents of al :"+al);
System.out.println("Size of al :"+al.size());
}
}
```

Output for Adding Element and Size of ArrayList

 ```Initial ArrayList : [] Size of al :2 Contents of al :[A, B] Contents of al :[A, C, B] Size of al :3 ```

Get and Set ArrayList Element

• Returns the element at the specified position in this list. Throws IndexOutOfBoundsException if the specified index is is out of range (index < 0 or index >= size()).
```Object get(int index)
```
• Replaces the element at the specified position in this list with the specified element. Throws IndexOutOfBoundsException if the specified index is is out of range (index < 0 or index >= size()).
```Object set(int index, Object element)
```

Find Index of ArrayList Element

• Returns the index in this list of the first occurrence of the specified element, or -1 if the List does not contain this element.
```int indexOf(Object o)
```
• Returns the index in this list of the last occurrence of the specified element, or -1 if the list does not contain this element.
```int lastIndexOf(Object o)
```

Find Element Contain in ArrayList

• Returns true if this list contains the specified element. More formally, returns true if and only if this list contains at least one element e such that (o==null ? e==null : o.equals(e)).
```boolean contains(Object o)
```

Different Method in ArrayList

```
public class ArrayListDemo {
public static void main(String[] args) {
// create an array list
ArrayList al = new ArrayList();

// add elements to the array list
System.out.println("Contents of al : " + al);

// find index of element in ArrayList
System.out.println("Index of D : " + al.indexOf("D"));
System.out.println("Index of A : " + al.indexOf("A"));

// find index of element in ArrayList
System.out.println("Index of A : " + al.lastIndexOf("A"));

// get element at given Index
System.out.println("Element at Second Index : " + al.get(2));
System.out.println("Element at Sixth Index : " + al.get(6));

//set element at given Index
al.set(3,"B"); // replacing third index element by "B"
System.out.println("Contents of al : " + al);

//check ArrayList contains given element
System.out.println("ArrayList contain D : "+al.contains("D"));
System.out.println("ArrayList contain F : "+al.contains("F"));
}
}
```

Output for Different Method in ArrayList

 ```Contents of al : [A, B, C, A, D, A, E] Index of D : 4 Index of A : 0 Index of A : 5 Element at Second Index : C Element at Sixth Index : E Contents of al : [A, B, C, B, D, A, E] ArrayList contain D : true ArrayList contain F : false ```

Question: Consider the following code:

 ```public class ArrayListDemo { public static void main(String[] args) { ArrayList al = new ArrayList(); al.add("A"); al.add("B"); al.add("C"); al.add("E"); al.add("F"); al.remove(2); al.remove("F"); al.set(1, "G"); al.add("H"); al.set(3, "I"); System.out.println("Size of al : " + al.size()); System.out.println("Contents of al : " + al); } } ```

In the example above, what is output?

 ```Size of al : 4 Contents of al : [A, G, E, I] ```

Some more ArrayList methods:

Method Description
`Object clone()` Returns a shallow copy of this ArrayList.
`Object[] toArray()` Returns an array containing all of the elements in this list in the correct order. Throws NullPointerException if the specified array is null.
`void trimToSize()` Trims the capacity of this ArrayList instance to be the list's current size.
`void ensureCapacity(int minCapacity)` Increases the capacity of this ArrayList instance, if necessary, to ensure that it can hold at least the number of elements specified by the minimum capacity argument.
`protected void removeRange(int fromIndex, int toIndex)` Removes from this List all of the elements whose index is between fromIndex, inclusive and toIndex, exclusive.

Map

Aside from the `java.util.Collection` interface, the Java JDK has the `java.util.Map` interface as well. It is sometimes also called an Associated Array or a Dictionary. A map defines key value mappings. Implementations of the Map interface do not contain collections of objects. Instead they contain collections of key->value mappings. It can be thought of as an array where the index doesn't need to be an integer.

 Code section 5.17: Use of a map. ```1 import java.util.Map; 2 import java.util.Hashtable; 3 ... 4 Map map = new Hashtable(); 5 ... 6 map.put(key, value); ```

Use the Map interface if you need to keep related objects together in a Map where you can:

• Access an element by a key object
• Map one object to other

 Figure 5.6: Map Interfaces.

java.util.Map<K,V>
maps keys to values. A map cannot contain duplicate keys; each key can map to at most one value. The Map interface provides three collection views, which allow a map's contents to be viewed as a set of keys, collection of values, or set of key-value mappings. The key is usually a non-mutable object. The value object however can be a mutable object.
java.util.SortedMap<K,V>
same as the Map interface, plus the keys in the Map are sorted.

In the above example, the same operations are made with two different map implementations:

 Code listing 5.4: MapImplementations.java ``` 1 import java.util.LinkedHashMap; 2 import java.util.Map; 3 import java.util.TreeMap; 4 5 /** 6 * Compare the map implementations. 7 * 8 * @author xxx 9 */ 10 public class MapImplementations { 11 12 /** 13 * Compare the map implementations. 14 * @param args The execution parameters. 15 */ 16 public static void main(String[] args) { 17 processMap(new LinkedHashMap()); 18 19 processMap(new TreeMap()); 20 } 21 22 /** 23 * Use a map: 24 * 1. Fill the map with key-> value. 25 * 2. Print all the keys. 26 * 27 * @param map The used map. 28 */ 29 public static void processMap(Map map) { 30 System.out.println("Process the map"); 31 map.put("3", new Integer(3)); 32 map.put("2", new Integer(2)); 33 map.put("1", new Integer(1)); 34 35 for (String key : map.keySet()) { 36 System.out.println(key); 37 } 38 } 39 } ```
 Console for Code listing 5.4 ```Process the map 3 2 1 Process the map 1 2 3 ```

We see that only the `TreeMap` has sorted the keys. Beware of the generics. The Map interface is tricky. The methods `get()` and `remove()` are not generic. This means that you must be careful of the type of the key:

 Code section 5.18: Tricky generics. ``` 1 Map map = new TreeMap(); 2 3 map.put(new Integer(1), "Watch"); 4 map.put(new Integer(2), "out"); 5 map.put(new Integer(3), "!"); 6 7 map.remove("2"); 8 9 for (String value : map.values()) { 10 System.out.println(value); 11 } ```
 Console for Code section 5.18 ```Watch out ! ```

The `remove()` call has done nothing because `"2"` is a `String`, not an `Integer` so no key and value has been found and removed.

Map Classes

The Map interface has the following implementations:

 Figure 5.7: Map class diagram.

java.util.TreeMap<E>
guarantees that the map will be in ascending key order, sorted according to the natural order for the key's class, not-synchronized.
java.util.Hashtable<E>
Synchronized, null can not be used as key
java.util.HashMap<E>
is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls
java.util.concurrent.ConcurrentHashMap
same as Hashtable, plus retrieval operations (including get) generally do not block, so may overlap with update operations (including put and remove).
java.util.WeakHashMap<E>
entry in a WeakHashMap will automatically be removed when its key is no longer in ordinary use. Non-synchronized.
This linked list defines the iteration ordering, which is normally the order in which keys were first inserted into the map (first insertion-order). Note that insertion order is not affected if a key is re-inserted into the map.
java.util.IdentityHashMap
This class implements the Map interface with a hash table, using reference-equality in place of object-equality when comparing keys (and values). In other words, in an IdentityHashMap, two keys k1 and k2 are considered equal if and only `if (k1==k2)`. (In normal Map implementations (like HashMap) two keys k1 and k2 are considered equal if and only `if (k1==null ? k2==null : k1.equals(k2))`.) Not-synchronized.
java.util.EnumMap
All of the keys in an enum map must come from a single enum type that is specified, explicitly or implicitly, when the map is created. Enum maps are represented internally as arrays. This representation is extremely compact and efficient. Not-synchronized.

The following table lists all the synchronized map classes:

synchronized non-synchronized
java.util.TreeMap
java.util.Hashtable

java.util.concurrent.ConcurrentHashMap

java.util.HashMap
java.util.IdentityHashMap
java.util.EnumMap

Comparing Objects

In Java, we can distinguish two kinds of equality.

• Object reference equality: when two object references point to the same object.
• Object value equality: when two separate objects happen to have the same values/state.

If two objects are equal in reference, they are equal in value too.

Comparing for reference equality

The `==` operator can be used to check if two object references point to the same object.

 Code section 5.19: Reference equality. ```1 if (objRef1 == objRef2) { 2 // The two object references point to the same object 3 } ```

Comparing for value equality

To be able to compare two Java objects of the same class the `boolean equals(Object obj)` method must be overriden and implemented by the class.

The implementor decides which values must be equal to consider two objects to be equal. For example in the below class, the `name` and the `address` must be equal but not the `description`.

 Code listing 5.5: Customer.java ``` 1 public class Customer { 2 private String name; 3 private String address; 4 private String description; 5 // ... 6 public boolean equals(Object obj) { 7 if (this == obj) { 8 return true; 9 } else if (obj == null) { 10 return false; 11 } else if (obj instanceof Customer) { 12 Customer cust = (Customer) obj; 13 if ((cust.getName() == null && name == null) || 14 (cust.getName().equals(name) && ((cust.getAddress() == null && address == null) 15 || cust.getAddress().equals(address))) { 16 return true; 17 } 18 } 19 return false; 20 } 21 22 } ```

After the `equals()` method is overriden, two objects from the same class can be compared like this:

 Code section 5.20: Method usage. ```1 Customer cust1 = new Customer(); 2 Customer cust2 = new Customer(); 3 //... 4 if (cust1.equals(cust2)) { 5 // Two Customers are equal, by name and address 6 } ```

Note that equal objects must have equal hash codes. Therefore, when overriding the `equals` method, you must also override the `hashCode` method. Failure to do so violates the general contract for the `hashCode` method, and any classes that use the hash code, such as `HashMap` will not function properly.

Sorting/Ordering

In Java, there are several existing methods that already sort objects from any class like `Collections.sort(List<T> list)`. However, Java needs to know the comparison rules between two objects. So when you define a new class and want the objects of your class to be sortable, you have to implement the `Comparable` and redefine the `compareTo(Object obj)` method.

`int` compareTo(T o)
Compares two objects and return an integer:
• A negative integer means that the current object is before the parameter object in the natural ordering.
• Zero means that the current object and the parameter object are equal.
• A positive integer means that the current object is after the parameter object in the natural ordering.

Let's say that the name is more important than the address and the description is ignored.

 Code listing 5.6: SortableCustomer.java ``` 1 public class SortableCustomer implements Comparable { 2 private String name; 3 private String address; 4 private String description; 5 // ... 6 public int compareTo(SortableCustomer anotherCustomer) { 7 if (name.compareTo(anotherCustomer.getName()) == 0) { 8 return address.compareTo(anotherCustomer.getAddress(); 9 } else { 10 return name.compareTo(anotherCustomer.getName(); 11 } 12 } 13 14 } ```

Objects that implement this interface can be used as keys in a sorted map or elements in a sorted set, without the need to specify a comparator.

The natural ordering for a class C is said to be consistent with equals if and only if `e1.compareTo((Object) e2) == 0` has the same boolean value as `e1.equals((Object) e2)` for every e1 and e2 of class C. Note that null is not an instance of any class, and `e.compareTo(null)` should throw a NullPointerException even though `e.equals(null)` returns false.

It is strongly recommended (though not required) that natural orderings be consistent with equals. This is because sorted sets (and sorted maps) without explicit comparators behave "strangely" when they are used with elements (or keys) whose natural ordering is inconsistent with equals. In particular, such a sorted set (or sorted map) violates the general contract for set (or map), which is defined in terms of the equals method.

Change Sorting/Ordering

Sometimes we may want to change the ordering of a collection of objects from the same class. We may want to order descending or ascending order. We may want to sort by `name` or by `address`.

We need to create a class for each way of ordering. It has to implement the `Comparator` interface.

Since Java 5.0, the `Comparator` interface is generic; that means when you implement it, you can specify what type of objects your comparator can compare.

 Code listing 5.7: CustomerComparator.java ```1 public class CustomerComparator implements Comparator { 2 public int compare(Customer cust1, Customer cust2) { 3 return cust1.getName().compareTo(cust2.getName()); 4 } 5 } ```

The above class then can be associated with a SortedSet or other collections that support sorting.

 Code section 5.21: Comparator usage. ```1 Collection orderedCustomers = new TreeSet(new CustomerComparator()); ```

Using the Iterator the `orderedCustomers` collection can be iterated in order of sorted by `name`.

A List can be sorted by the `Collections`' `sort` method.

 Code section 5.22: Customized comparison. ```1 java.util.Collections.sort(custList, new CustomerComparator()); ```

Sorts the specified list according to the order induced by the specified comparator. All elements in the list must be mutually comparable using the specified comparator.

An array of objects can also be sorted with the help of a `Comparator`.

 Code section 5.23: Array sorting. ```1 SortableCustomer[] customerArray; 2 //... 3 java.util.Arrays.sort(customerArray, new CustomerComparator()); ```

Sorts the specified array of `Customer` objects (customerArray) according to the order induced by the specified comparator. All elements in the array must be mutually comparable by the specified comparator.

Exceptions

The ideal time to catch an error is at compile time, before you even try to run the program. However, not all errors can be detected at compile time. The rest of the problems must be handled at run time through some formality that allows the originator of the error to pass appropriate information to a recipient who will know how to handle the difficulty properly.

Improved error recovery is one of the most powerful ways that can increase the robustness of your code. Error recovery is a fundamental concern for every program you write, but it's especially important in Java, where one of the primary goals is to create program components for others to use. To create a robust system, each component must be robust. By providing a consistent error-reporting model using exceptions, Java allows components to reliably communicate problems to client code.

Flow of code execution

In Java, there are two main flows of code executions.

• Normal main sequential code execution, the program doing what it meant to accomplish.
• Exception handling code execution, the main program flow was interrupted by an error or some other condition that prevent the continuation of the normal main sequential code execution.
Exception
Exceptions are Java's way of error handling. Whenever an unexpected condition occurs, an exception can be thrown with an exception object as a parameter. It means that the normal program control flow stops and the search for a `catch` block begins. If that is not found at the current method level the search continues at the caller method level, until a matching `catch` block is found. If none is found the exception will be handled by the JVM, and usually the java program terminates.
When a `catch` "matching" block is found, that block will be executed, the exception object is passed to the block as a parameter. Then normal program execution continues after the `catch` block. See Java exception handling syntax.
Exception Object
This is the object that is "thrown" as a parameter from the error, and passed to the `catch` block. Exception object encapsulates the information about the error's location and its nature. All Exception objects must be inherited from the `java.lang.Throwable`. See the UML diagram below.
 Figure 6.1: Java exception classes

Matching rule
A thrown exception object can be caught by the `catch` keyword and specifying the exception object's class or its super-class.
Naming convention
It is good practice to add Exception to all exception classes. Also the name of the exception should be meaningful, should represent the problem. For example `CustomerNotFoundException` indicate that customer was not found.

Throwing and Catching Exceptions

Language compilers are adept at pointing out most of the erroneous code in a program, however there are some errors that only become apparent when the program is executed. Consider the code listing 6.1; here, the program defines a method divide that does a simple division operation taking two integers as parameter arguments and returning the result of their division. It can safely be assumed that when the divide(4, 2) statement is called, it would return the number 2. However, consider the next statement, where the program relies upon the provided command line arguments to generate a division operation. What if the user provides the number zero (0) as the second argument? We all know that division by zero is impossible, but the compiler couldn't possibly have anticipated the user providing zero as an argument.

 Code listing 6.1: SimpleDivisionOperation.java ``` 1 public class SimpleDivisionOperation { 2 public static void main(String[] args) { 3 System.out.println(divide(4, 2)); 4 if (args.length > 1) { 5 int arg0 = Integer.parseInt(args[0]); 6 int arg1 = Integer.parseInt(args[1]); 7 System.out.println(divide(arg0, arg1)); 8 } 9 } 10 11 public static int divide(int a, int b) { 12 return a / b; 13 } 14 } ```
 Output for Code listing 6.1 ```\$ java SimpleDivisionOperation 1 0 2 Exception in thread "main" java.lang.ArithmeticException: / by zero at SimpleDivisionOperation.divide(SimpleDivisionOperation.java:12) at SimpleDivisionOperation.main(SimpleDivisionOperation.java:7) ```

Such exceptional code that results in erroneous interpretations at program runtime usually results in errors that are called exceptions in Java. When the Java interpreter encounters an exceptional code, it halts execution and displays information about the error that occurs. This information is known as a stack trace. The stack trace in the above example tells us more about the error, such as the thread — `"main"` — where the exception occurred, the type of exception — `java.lang.ArithmeticException`, a comprehensible display message — `/ by zero`, and the exact methods and the line numbers where the exception may have occurred.

Exception object

The preceding exception could have been created explicitly by the developer as it is the case in the following code:

 Code listing 6.2: SimpleDivisionOperation.java ``` 1 public class SimpleDivisionOperation { 2 public static void main(String[] args) { 3 System.out.println(divide(4, 2)); 4 if (args.length > 1) { 5 // Convert a string to an integer 6 int arg0 = Integer.parseInt(args[0]); 7 int arg1 = Integer.parseInt(args[1]); 8 System.out.println(divide(arg0, arg1)); 9 } 10 } 11 12 public static int divide(int a, int b) { 13 if (b == 0) { 14 throw new ArithmeticException("You can\'t divide by zero!"); 15 } else { 16 return a / b; 17 } 18 } 19 } ```
 Output for Code listing 6.2 ```\$ java SimpleDivisionOperation 1 0 2 Exception in thread "main" java.lang.ArithmeticException: You can't divide by zero! at SimpleDivisionOperation.divide(SimpleDivisionOperation.java:14) at SimpleDivisionOperation.main(SimpleDivisionOperation.java:7) ```

Note that when `b` equals zero, there is no return value. Instead of a `java.lang.ArithmeticException` generated by the Java interpreter itself, it is an exception created by the coder. The result is the same. It shows you that an exception is an object. Its main particularity is that it can be thrown. An exception object must inherit from `java.lang.Exception`. Standard exceptions have two constructors:

1. The default constructor; and,
2. A constructor taking a string argument so that you can place pertinent information in the exception.
 Code section 6.1: Instance of an exception object with the default constructor. ```1 new Exception(); ```
 Code section 6.2: Instance of an `Exception` object by passing string in constructor. ```1 new Exception("Something unexpected happened"); ```

This string can later be extracted using various methods, as you can see in the code listing 6.2.

You can throw any type of Throwable object using the keyword `throw`. It interrupts the method. Anything after the throw statement would not be executed, unless the thrown exception is handled. The exception object is not returned from the method, it is thrown from the method. That means that the exception object is not the return value of the method and the calling method can be interrupted too and so on and so on...

Typically, you'll throw a different class of exception for each different type of error. The information about the error is represented both inside the exception object and implicitly in the name of the exception class, so someone in the bigger context can figure out what to do with your exception. Often, the only information is the type of exception, and nothing meaningful is stored within the exception object.

Oracle standard exception classes

The box 6.1 below talks about the various exception classes within the `java.lang` package.

 Box 6.1: The Java exception classes Throwable  The Throwable class is the superclass of all errors and exceptions in the Java language. Only objects that are instances of this class (or one of its subclasses) are thrown by the Java Virtual Machine or can be thrown by the Java throw statement. A throwable contains a snapshot of the execution stack of its thread at the time it was created. It can also contain a message string that gives more information about the error. Finally, it can contain a cause: another throwable that caused this throwable to get thrown. The cause facility was added in release 1.4. It is also known as the chained exception facility, as the cause can, itself, have a cause, and so on, leading to a "chain" of exceptions, each caused by another. Error  An Error indicates serious problems that a reasonable application should not try to handle. Most such errors are abnormal conditions. Exception  The class Exception and its subclasses are a form of Throwable that indicates conditions that a reasonable application might want to handle. Also this is the class that a programmer may want to extend when adding business logic exceptions. RuntimeException  RuntimeException is the superclass of those exceptions that can be thrown during the normal operation of the Java Virtual Machine. A method is not required to declare in its throws clause any subclasses of RuntimeException that might be thrown during the execution of the method but not caught. Figure 6.2: The exception classes and their inheritance model in the JCL.

`try`/`catch` statement

By default, when an exception is thrown, the current method is interrupted, the calling method is interrupted too and so on till the `main` method. A thrown exception can also be caught using a `try`/`catch` statement. Below is how a `try`/`catch` statement works:

 Code section 6.3: Division into a `try` block. ``` 1 int a = 4; 2 int b = 2; 3 int result = 0; 4 try { 5 int c = a / b; 6 result = c; 7 } catch(ArithmeticException ex) { 8 result = 0; 9 } 10 return result; ```

The executed code lines have been highlighted. When no exception is thrown, the method flow executes the `try` statement and not the `catch` statement.

 Code section 6.4: Catching 'division by zero' errors. ``` 1 int a = 4; 2 int b = 0; 3 int result = 0; 4 try { 5 int c = a / b; 6 result = c; 7 } catch(ArithmeticException ex) { 8 result = 0; 9 } 10 return result; ```

As there is a thrown exception at line 5, the line 6 is not executed, but the exception is caught by the `catch` statement so the `catch` block is executed. The following code is also executed. Note that the `catch` statement takes an exception as parameter. There is a third case: when the exception is not from the same class as the parameter:

 Code section 6.5: Uncaught exception. ``` 1 int a = 4; 2 int b = 0; 3 int result = 0; 4 try { 5 int c = a / b; 6 result = c; 7 } catch(NullPointerException ex) { 8 result = 0; 9 } 10 return result; ```

It is as if there is no `try`/`catch` statement. The exception is thrown to the calling method.

`catch` blocks

A `try`/`catch` statement can contain several `catch` blocks, to handle different exceptions in different ways. Each `catch` block must take a parameter of a different throwable class. A thrown object may match several `catch` block but only the first `catch` block that matches the object will be executed. A catch-block will catch a thrown exception if and only if:

• the thrown exception object is the same as the exception object specified by the catch-block.
• the thrown exception object is the subtype of the exception object specified by the catch-block.

This means that the `catch` block order is important. As a consequence, you can't put a `catch` block that catches all the exception (which take a `java.lang.Exception` as parameter) before a `catch` block that catches a more specific exception as the second block could never be executed.

 Code section 6.6: Exception handling with catch blocks. ``` 1 try { 2 // Suppose the code here throws any exceptions, 3 // then each is handled in a separate catch block. 4 5 int[] tooSmallArray = new int[2]; 6 int outOfBoundsIndex = 10000; 7 tooSmallArray[outOfBoundsIndex] = 1; 8 9 System.out.println("No exception thrown."); 10 } catch(NullPointerException ex) { 11 System.out.println("Exception handling code for the NullPointerException."); 12 } catch(NumberFormatException ex) { 13 System.out.println("Exception handling code for the NumberFormatException."); 14 } catch(ArithmeticException | IndexOutOfBoundsException ex) { 15 System.out.println("Exception handling code for ArithmeticException" 16 + " or IndexOutOfBoundsException."); 17 } catch(Exception ex) { 18 System.out.println("Exception handling code for any other Exception."); 19 } ```
 Output for Code section 6.6 ```Exception handling code for ArithmeticException or IndexOutOfBoundsException. ```

At line 14, we use a multi-catch clause. It is available since the JDK 7. This is a combination of several catch clauses and let's you handle exceptions in a single handler while also maintaining their types. So, instead of being boxed into a parent Exception super-class, they retain their individual types.

You can also use the `java.lang.Throwable` class here, since Throwable is the parent class for the application-specific Exception classes. However, this is discouraged in Java programming circles. This is because Throwable happens to also be the parent class for the non-application specific Error classes which are not meant to be handled explicitly as they are catered for by the JVM itself.

`finally` block

A `finally` block can be added after the `catch` blocks. A `finally` block is always executed, even when no exception is thrown, an exception is thrown and caught, or an exception is thrown and not caught. It's a place to put code that should always be executed after an unsafe operation like a file close or a database disconnection. You can define a `try` block without `catch` block, however, in this case, it must be followed by a `finally` block.

Example of handling exceptions

Let's examine the following code:

 Code section 6.7: Handling exceptions. ``` 1 public void methodA() throws SomeException { 2 // Method body 3 } 4 5 public void methodB() throws CustomException, AnotherException { 6 // Method body 7 } 8 9 public void methodC() { 10 methodB(); 11 methodA(); 12 } ```

In the code section 6.7, `methodC` is invalid. Because `methodA` and `methodB` pass (or throw) exceptions, `methodC` must be prepared to handle them. This can be handled in two ways: a `try`-`catch` block, which will handle the exception within the method and a `throws` clause which would in turn throw the exception to the caller to handle. The above example will cause a compilation error, as Java is very strict about exception handling. So the programmer is forced to handle any possible error condition at some point.

A method can do two things with an exception: ask the calling method to handle it by the `throws` declaration or handle the exception inside the method by the `try`-`catch` block.

To work correctly, the original code can be modified in multiple ways. For example, the following:

 Code section 6.8: Catching and throwing exceptions. ```1 public void methodC() throws CustomException, SomeException { 2 try { 3 methodB(); 4 } catch(AnotherException e) { 5 // Handle caught exceptions. 6 } 7 methodA(); 8 } ```

The `AnotherException` from `methodB` will be handled locally, while `CustomException` and `SomeException` will be thrown to the caller to handle it. Most of the developers are embarrassed when they have to choose between the two options. This type of decision should not be taken at development time. If you are a development team, it should be discussed between all the developers in order to have a common exception handling policy.

Keyword references

• `try`
• `catch`
• `finally`
• `throws`
• `throw`

Checked Exceptions

A checked exception is a type of exception that must be either caught or declared in the method in which it is thrown. For example, the `java.io.IOException` is a checked exception. To understand what is a checked exception, consider the following code:

 Code section 6.9: Unhandled exception. ```1 public void ioOperation(boolean isResourceAvailable) { 2 if (!isResourceAvailable) { 3 throw new IOException(); 4 } 5 } ```

This code won't compile because it can throw a checked exception. The compilation error can be resolved in either of two ways: By catching the exception and handling it, or by declaring that the exception can be thrown using the `throws` keyword.

 Code section 6.10: Catching an exception. ```1 public void ioOperation(boolean isResourceAvailable) { 2 try { 3 if (!isResourceAvailable) { 4 throw new IOException(); 5 } 6 } catch(IOException e) { 7 // Handle caught exceptions. 8 } 9 } ```
 Code section 6.11: Declaring an exception. ```1 public void ioOperation(boolean isResourceAvailable) throws IOException { 2 if (!isResourceAvailable) { 3 throw new IOException(); 4 } 5 } ```

In the Java class hierarchy, an exception is a checked exception if it inherits from `java.lang.Throwable`, but not from `java.lang.RuntimeException` or `java.lang.Error`. All the application or business logic exceptions should be checked exceptions.

It is possible that a method declares that it can throw an exception, but actually it does not. Still, the caller has to deal with it. The checked exception declaration has a domino effect. Any methods that will use the previous method will also have to handle the checked exception, and so on.

So the compiler for the Java programming language checks, at compile time, that a program contains handlers for all application exceptions, by analyzing each method body. If, by executing the method body, an exception can be thrown to the caller, that exception must be declared. How does the compiler know whether a method body can throw an exception? That is easy. Inside the method body, there are calls to other methods; the compiler looks at each of their method signature, what exceptions they declared to throw.

Why Force Exception Handling?

This may look boring to the developer but it forces them to think about all the checked exceptions and increase the code quality. This compile-time checking for the presence of exception handlers is designed to make the application developer life easier. To debug whether a particular thrown exception has a matching catch would be a long process. In conventional languages like C, and C++, a separate error handling debugging were needed. In java we can be sure that when an application exception is thrown, that exception somewhere in the program is handled. In C, and C++, that has to be tested. In Java that does not need to be tested, so the freed up time can be used for more meaningful testing, testing the business features.

What Exceptions can be Declared when Overriding a Method?

The checked exception classes specified after the `throws` keyword are part of the contract between the implementer and user. An overriding method can declare the same exceptions, subclasses or no exceptions.

What Exceptions can be Declared when Implementing an Interface?

When interfaces are involved, the implementation declaration must have a throws-clause that is compatible with the interface declarations.

Unchecked Exceptions

Unchecked, uncaught or runtime exceptions are exceptions that can be thrown without being caught or declared:

 Code section 6.12: Throwing an exception without declaring it or catching it. ```1 public void futureMethod() { 2 throw new RuntimeException("This method is not yet implemented"); 3 } ```

...however, you can still declare and catch such exceptions. Runtime exceptions are not business exceptions. They are usually related to hard-coded issues like data errors, arithmetic overflow, divide by zero etc. In other words, errors that can't be worked around nor anticipated. The most famous (and feared) runtime exception is the `NullPointerException`.

A runtime exception must be or inherit from the `RuntimeException` class or the `Error` class.

Sometime it is desirable to catch all exceptions for logging purposes, then throw them back in. For example, in servlet programming when an application server calls the server `getLastModified()`, we want to monitor that no exceptions happened during the serving of the request. The application has its own logging separate from the server logging so the runtime exceptions would just go through without being detected by the application. The following code checks all exceptions, logs them and throws them back again.

 Code section 6.13: Logging an exception. ``` 1 public long getLastModified(HttpServletRequest req) { 2 try { 3 ... 4 return getTimeStamp(); 5 ... 6 } catch(RuntimeException e) { 7 log.error("Error during handling post request", e); 8 9 throw e; 10 } 11 } ```

In the above code, all business logic exception are handled in the `getTimeStamp()` method. Runtime exceptions are caught for logging purposes, and then thrown back to the server to be handled.

Preventing NullPointerException

`NullPointerException` is a `RuntimeException`. In Java, a special `null` value can be assigned to an object reference. `NullPointerException` is thrown when an application attempts to use an object reference that has the `null` value. These include:

• Calling an instance method on the object referred by a null reference.
• Accessing or modifying an instance field of the object referred by a null reference.
• If the reference type is an array type, taking the length of a null reference.
• If the reference type is an array type, accessing or modifying the slots of a null reference.
• If the reference type is a subtype of `Throwable`, throwing a null reference.

Applications should throw instances of this class to indicate other illegal uses of the null object.

 Code section 6.13: Null pointer. ```1 Object obj = null; 2 obj.toString(); // This statement will throw a NullPointerException ```

The above code shows one of the pitfalls of Java and the most common source of bugs. No object is created and the compiler does not detect it. `NullPointerException` is one of the most common exceptions thrown in Java.

Why do we need `null`?

The reason we need it is because many times we need to create an object reference before the object itself is created. Object references cannot exist without a value, so we assign the `null` value to it.

 Code section 6.14: Non-instantiated declared object. ```1 public Person getPerson(boolean isWoman) { 2 Person person = null; 3 if (isWoman) { 4 person = createWoman(); 5 } else { 6 person = createMan(); 7 } 8 return person; 9 } ```

In code section 6.14 we want to create the `Person` inside the if-else, but we also want to return the object reference to the caller, so we need to create the object reference outside of the if-else, because of the scoping rule in Java. Incorrect error-handling and poor contract design can be a pitfall with any programming language. This is also true for Java.

Now we will describe how to prevent `NullPointerException`. We do not describe general techniques for how you should program Java, we just hope to make you more aware of null values, and to be more careful about generating them yourself.

This list is not complete — there are no rules for preventing `NullPointerException` entirely in Java, because the standard libraries have to be used, and they can cause `NullPointerException`s. Also, it is possible to observe an uninitialized final field in Java, so you can't even treat a final field as being completely trusted during the object's creation.

A good approach is to learn how to deal with `NullPointerException`s first, and become competent with that. These suggestions will help you to cause less `NullPointerException`s, but they don't replace the need to know about `NullPointerException`s.

Comparing string variable with a string literal

When you compare a variable with a string literal, most of people would do that this way:

 Code section 6.15: Bad comparison. ```1 if (state.equals("OK")) { 2 ... 3 } ```

Always put the string literal first:

 Code section 6.16: Better comparison. ```1 if ("OK".equals(state)) { 2 ... 3 } ```

If the `state` variable is null, you get a `NullPointerException` in the first example, but not in the second one.

Minimize the use of the keyword 'null' in assignment statements

This means not doing things like:

 Code section 6.17: Declaring an exception. ``` 1 String s = null; 2 while (something) { 3 if (something2) { 4 s = "yep"; 5 } 6 } 7 8 if (s != null) { 9 something3(s); 10 } ```

You can replace this with:

 Code section 6.18: Declaring an exception. ```1 boolean done = false; 2 3 while (!done && something) { 4 if (something2) { 5 done = true; 6 something3("yep"); 7 } 8 } ```

You might also consider replacing null with "" in the first example, but default values bring about bugs caused by default values being left in place. A `NullPointerException` is actually better, as it allows the runtime to tell you about the bug, rather than just continue with a default value.

Minimize the use of the new Type[int] syntax for creating arrays of objects

An array created using `new Object[10]` has 10 null pointers. That's 10 more than we want, so use collections instead, or explicitly fill the array at initialization with:

 Code section 6.19: Declaring an exception. ```1 Object[] objects = {"blah", 5, new File("/usr/bin")}; ```

or:

 Code section 6.20: Declaring an exception. ```1 Object[] objects; 2 objects = new Object[]{"blah", 5, new File("/usr/bin")}; ```

Check all references obtained from 'untrusted' methods

Many methods that can return a reference can return a null reference. Make sure you check these. For example:

 Code section 6.21: Declaring an exception. ```1 File file = new File("/etc"); 2 File[] files = file.listFiles(); 3 if (files != null) { 4 stuff 5 } ```

`File.listFiles()` can return null if `/etc` is not a directory.

You can decide to trust some methods not to return null, if you like, but that's an assumption you're making. Some methods that don't specify that they might return null, actually do, instead of throwing an exception.

For each loop trap

Beware if you loop on an array or a collection in a for each loop.

 Code section 6.22: Visit a collection. ```1 Collection myNumbers = buildNumbers(); 2 for (Integer myNumber : myNumbers) { 3 System.out.println(myNumber); 4 } ```

If the object is null, it does not just do zero loops, it throws a null pointer exception. So don't forget this case. Add an `if` statement or return empty collections:

 Code section 6.23: Visit a collection safety. ```1 Collection myNumbers = buildNumbers(); 2 if (myNumbers != null) { 3 for (Integer myNumber : myNumbers) { 4 System.out.println(myNumber); 5 } 6 } ```

External tools

There are tools like FindBugs that parse your code and warn you about potential bugs. Most of the time, these tools detect possible null pointers.

Stack trace

Stack Trace is a list of method calls from the point when the application was started to the point where the exception was thrown. The most recent method calls are at the top.

 Code listing 6.3: StackTraceExample.java ``` 1 public class StackTraceExample { 2 public static void main(String[] args) { 3 method1(); 4 } 5 6 public static void method1() { 7 method11(); 8 } 9 10 public static void method11() { 11 method111(); 12 } 13 14 public static void method111() { 15 throw new NullPointerException("Fictitious NullPointerException"); 16 } 17 } ```
 Output for Code listing 6.3 ```Exception in thread "main" java.lang.NullPointerException: Fictitious NullPointerException at StackTraceExample.method111(StackTraceExample.java:15) at StackTraceExample.method11(StackTraceExample.java:11) at StackTraceExample.method1(StackTraceExample.java:7) at StackTraceExample.main(StackTraceExample.java:3) ```

The stack trace can be printed to the standard error by calling the `public void printStackTrace()` method of an exception.

From Java 1.4, the stack trace is encapsulated into an array of a java class called `java.lang.StackTraceElement`. The stack trace element array returned by `Throwable.getStackTrace()` method. Each element represents a single stack frame. All stack frames except for the one at the top of the stack represent a method invocation. The frame at the top of the stack represents the execution point at which the stack trace was generated. Typically, this is the point at which the throwable corresponding to the stack trace was created.

A stack frame represents the following information:

 Code section 6.24: Stack frame. ```1 public StackTraceElement(String declaringClass, 2 String methodName, 3 String fileName, 4 int lineNumber); ```

Creates a stack trace element representing the specified execution point.

Converting the stack trace into string

Many times for debugging purposes, we'd like to convert the stack trace to a `String` so we can log it to our log file.

The following code shows how to do that:

 Code section 6.25: Save the stack trace. ``` 1 import java.io.StringWriter; 2 import java.io.PrintWriter; 3 4 ... 5 6 Exception e = new NullPointerException(); 7 8 StringWriter outError = new StringWriter(); 9 e.printStackTrace(new PrintWriter(outError)); 10 String errorString = outError.toString(); 11 12 // Do whatever you want with the errorString ```

Nesting Exceptions

When an exception is caught, the exception contains the stack-trace, which describes the error and shows where the exception happened (i.e. where the problem is and where the application programmer should look to fix the problem). Sometimes it is desirable to catch an exception and throw another exception. If the new exception keeps a reference to the first exception, the first exception is called a nesting exception.

 Code listing 6.4: NestingExceptionExample.java ``` 1 public class NestingExceptionExample { 2 3 public static void main(String[] args) throws Exception { 4 Object[] localArgs = (Object[]) args; 5 6 try { 7 Integer[] numbers = (Integer[]) localArgs; 8 } catch (ClassCastException originalException) { 9 Exception generalException = new Exception( 10 "Horrible exception!", 11 originalException); 12 throw generalException; 13 } 14 } 15 } ```
 Output for Code listing 6.4 ```Exception in thread "main" java.lang.Exception: Horrible exception! at NestingExceptionExample.main(NestingExceptionExample.java:9) Caused by: java.lang.ClassCastException: [Ljava.lang.String; incompatible with [Ljava.lang.Integer; at NestingExceptionExample.main(NestingExceptionExample.java:7) ```

The above code is an example of a nesting exception. When the `Exception` is thrown, by passing in the `ClassCastException` object reference as a parameter, the `ClassCastException` is nested in the newly created `Exception`, its stack-trace is appended together. When the `Exception` is caught, its stack-trace contains the original `ClassCastException`'s stack-trace.

This is a kind of exception conversion, from one exception to another. For example, calling a remote object using RMI, the calling method has to deal with `RemoteException` which is thrown if something is wrong during the communication. From the application point of view, `RemoteException` has no meaning, it should be transparent to the application that a remote object was used or not. So the `RemoteException` should be converted to an application exception.

This conversion can also hide where the error is originated. The stack-trace starts when the exception is thrown. So when we catch and throw a new exception, the stack-trace starts at when the new exception was thrown, losing the original stack-trace. This was true with the earlier version of Java (before 1.4). Since then, so called cause facility capabilities were built in the `Throwable` class.

A throwable contains a snapshot of the execution stack of its thread at the time it was created. It can also contain a message string that gives more information about the error. Finally, it can contain a cause: another throwable that caused this throwable to get thrown. The cause facility is also known as the chained exception facility, as the cause can, itself, have a cause, and so on, leading to a "chain" of exceptions, each caused by another.

A cause can be associated with a throwable in two ways: via a constructor that takes the cause as an argument, or via the `initCause(Throwable)` method. New throwable classes that wish to allow causes to be associated with them should provide constructors that take a cause and delegate (perhaps indirectly) to one of the `Throwable` constructors that takes a cause. For example:

 Code section 6.26: Chaining-aware constructor. ```1 try { 2 lowLevelOp(); 3 } catch (LowLevelException le) { 4 throw new HighLevelException(le); 5 } ```

Because the initCause method is public, it allows a cause to be associated with any throwable, even a "legacy throwable" whose implementation predates the addition of the exception chaining mechanism to Throwable. For example:

 Code section 6.27: Legacy constructor. ```1 try { 2 lowLevelOp(); 3 } catch (LowLevelException le) { 4 throw (HighLevelException) new HighLevelException().initCause(le); 5 } ```

Further, as of release 1.4, many general purpose Throwable classes (for example `Exception`, `RuntimeException`, `Error`) have been retrofitted with constructors that take a cause. This was not strictly necessary, due to the existence of the `initCause` method, but it is more convenient and expressive to delegate to a constructor that takes a cause.

By convention, class `Throwable` and its subclasses have two constructors, one that takes no arguments and one that takes a String argument that can be used to produce a detail message. Further, those subclasses that might likely have a cause associated with them should have two more constructors, one that takes a `Throwable` (the cause), and one that takes a String (the detail message) and a `Throwable` (the cause).

Concurrent Programming

In computer programming, an application program runs in a certain process of the CPU. Every statement that is then executed within the program is actually being executed in that process. In essence, when a statement is being executed, the CPU focuses all its attention on that particular statement and for the tiniest fraction of a second puts everything else on hold. After executing that statement, the CPU executes the next statement and so forth.

But consider for a moment that the execution of a particular statement is expected to take a considerable amount of time. You do not want to keep the CPU on halt until the statement gets executed and done with; you would want the CPU to continue with some other application process and resume the current application as smoothly as possible after its statement is executed. It can only be possible if you can run several processes simultaneously, such that when one process is executing a statement that is expected to take some time, another process in the queue would continue doing other things and so on. Such a principle of programming is called concurrent programming.

Throughout this chapter, we will be taking a look at concurrent programming constructs present in the Java programming language.

CPUs for any computer are designed to execute one task at any given time, yet we run multiple applications side-by-side and everything works in perfect congruence. It's not just because CPUs are extremely fast in performing calculations, it's because CPUs use a clever device of dividing their time amongst various tasks. Each application or task that is invoked on a computer gets associated with the CPU in the form of a process. A CPU therefore manages various processes, and jumps back and forth amongst each process giving it a fraction of its time and processing capability. This happens so fast that to a normal computer user it presents with the illusion of processes being run simultaneously. This capability of the CPU to divide its time amongst processes is called multitasking.

So, if we run a Java application on a computer, we are effectively creating a process with the CPU that gets a fraction of the CPU's time. In Java parlance, this main process gets called the daemon process or the daemon thread. But, Java goes one step further. It allows programmers to divide this daemon thread into several multiple threads which get executed simultaneously (much like a CPU) hence providing a Java application with a finer multitasking capability called multithreading.

In this section, we will take a look at what threads are and how multithreading is implemented within a Java program to make it appear congruent and effectively fast to respond.

In light of the above discussion, a thread is the smallest unit of processing that can be scheduled by an operating system. Therefore, using threads, a programmer can effectively create two or more tasks[1] that run at the same time. The first call-to-action is to implement a set of tasks that a particular thread would execute. To do so, we require the creation of a `Runnable` process.

Creating a Runnable process block

A `Runnable` process block is a simple class that implements a `run()` method. Within the `run()` method is the actual task that needs to be executed by a running thread. By implementing a class with the `Runnable` interface, we ensure that the class holds a `run()` method. Consider the following program:

 Code listing 1: A runnable process ```import java.util.Random; public class RunnableProcess implements Runnable { private String name; private int time; private Random rand = new Random(); public RunnableProcess(String name) { this.name = name; this.time = rand.nextInt(999); } public void run() { try { System.out.printf("%s is sleeping for %d \n", this.name, this.time); Thread.sleep(this.time); System.out.printf("%s is done.\n", this.name); } catch(Exception ex) { ex.printStackTrace(); } } } ```

In the above code, we create a class called `RunnableProcess` and implement the `Runnable` interface to ensure that we have a `run()` method in the class declaration.

 Code section 1.1: Implementing the `Runnable` interface ```public class RunnableProcess implements Runnable { ... public void run() { ... } } ```

We then declare the rest of the logic for the class. For the constructor, we take a `String` parameter that would serve as the name of the class. Then, we initialize the class member variable `time` with a random number between `0` and `999`. To ensure the initialization of a random number, we use the `Random` class in the `java.util` package.

 Code section 1.2: Including ability to generate random integers between `0` and `999` ```import java.util.Random; ... private Random rand = new Random(); ... this.time = rand.nextInt(999); ```

The actual task that would be executed per this runnable block is presented within the `run()` method. To keep safe from exceptions occurring because of the concurrent programming, we wrap the code within this method with a `try..catch` block. The executing task actually consists of just three statements. The first outputs the provided name for the Runnable process, and the last reports that the thread has executed. Perhaps the most intriguing part of the code is the second statement: `Thread.sleep(...)`.

 Code section 1.3: The actual runnable process task ```... System.out.printf("%s is sleeping for %d \n", this.name, this.time); Thread.sleep(this.time); System.out.printf("%s is done \n", this.name); ... ```

This statement allows the thread executing the current runnable block to halt its execution for the given amount of time. This time is presented in milliseconds. But for our convenience, this time would be the random number generated in the constructor and can be anywhere between `0` and `999` milliseconds. We will explore this in a later section. Creating a `Runnable` process block is just the beginning. No code is actually executed. To do so, we would require the creation of threads that would then individually execute this task.

Once we have a `Runnable` process block, we can create various threads that can then execute the logic encased within such blocks. Multithreading capabilities in Java are utilized and manipulated using the `Thread` class. A `Thread` object therefore holds all the necessary logic and devices to create truly multithreaded programs. Consider the following program:

 Code listing 2: Creating `Thread` objects ```public class ThreadLogic { public static void main(String[] args) { Thread t1 = new Thread(new RunnableProcess("Thread-1")); Thread t2 = new Thread(new RunnableProcess("Thread-2")); Thread t3 = new Thread(new RunnableProcess("Thread-3")); } } ```

Creating threads is as simple as the above program suggests. You just have to create an object of the `Thread` class and pass a reference to a `Runnable` process object. In the case above, we present the `Thread` constructor with the class object for the `RunnableProcess` class that we created in code listing 1. But for each object, we give a different name (i.e., `"Thread-1"` and `"Thread-2"`, etc.) to differentiate between the three `Thread` objects. The above example only declares `Thread` objects and hasn't yet started them for execution.

Now, that we know how to effectively create a `Runnable` process block and a `Thread` object that executes it, we need to understand how to start the created `Thread` objects. This couldn't be simpler. For this process, we will be calling the `start()` method on the `Thread` objects and voilà, our threads will begin executing their individual process tasks.

 Code listing 3: Starting the `Thread` objects ```public class ThreadLogic { public static void main(String[] args) { Thread t1 = new Thread(new RunnableProcess("Thread-1")); Thread t2 = new Thread(new RunnableProcess("Thread-2")); Thread t3 = new Thread(new RunnableProcess("Thread-3")); t1.start(); t2.start(); t3.start(); } } ```

The above code will start all three declared threads. This way, all three threads will begin their execution one-by-one. However, this being concurrent programming and us having declared random times for the halting of the execution, the outputs for every one of us would differ. Following is the output we received when we executed the above program.

 Output for code listing 3 ```Thread-1 is sleeping for 419 Thread-3 is sleeping for 876 Thread-2 is sleeping for 189 Thread-2 is done Thread-1 is done Thread-3 is done ```

It should be noted that the execution of the `Thread` didn't occur in the desired order. Instead of the order `t1``t2``t3`, the threads executed in the order of `t1``t3``t2`. The order in which the threads are executed is completely dependent on the operating system and may change for every execution of the program, thus making output of multithreaded application difficult to predict and control. Some people suggest that this is the major reason that adds to the complexity of multithreaded programming and its debugging. However, it should be observed that once the threads were put to sleep using the `Thread.sleep(...)` function, the execution intervals and order can be predicted quite capably. The thread with the least amount of sleeping time was `t2` (`"Thread-2"`) with `189` milliseconds of sleep hence it got called first. Then `t1` was called and finally `t3` was called.

It can be said that the execution order of the threads was manipulated to some degree using the `Thread.sleep(...)` method. The `Thread` class has such static methods that can arguably affect the execution order and manipulation of threads. Below are some useful static methods in the `Thread` class. These methods when called will only affect the currently running threads.

Method Description
`Thread.currentThread()` Returns the currently executing thread at any given time.
`Thread.dumpStack()` Prints a stack trace of the currently running thread.
`Thread.sleep(long millis)` Halts execution of the currently running thread for the given amount of time (in milliseconds).
throws `InterruptedException`
`Thread.sleep(long millis, int nanos)` Halts execution of the currently running thread for the given amount of time (in milliseconds plus provided nanoseconds).
throws `InterruptedException`
`Thread.yield()` Temporarily pauses the execution of the currently running thread to allow other threads to execute.

Synchronization

Given below is an example of creating and running multiple threads that behave in a synchronous manner such that when one thread is using a particular resource, the others wait until the resource has been released. We will talk more about this in later sections.

 Code listing 4: Creation of the multiple `Thread` objects running synchronously ```public class MultiThreadExample { public static boolean cthread; public static String stuff = " printing material"; public static void main(String args[]) { Thread t1 = new Thread(new RunnableProcess()); Thread t2 = new Thread(new RunnableProcess()); t1.setName("Thread-1"); t2.setName("Thread-2"); t2.start(); t1.start(); } /* * Prints information about the current thread and the index it is * on within the RunnableProcess */ public static void printFor(int index) { StringBuffer sb = new StringBuffer(); sb.append(Thread.currentThread().getName()).append(stuff); sb.append(" for the ").append(index).append(" time."); System.out.print(sb.toString()); } } class RunnableProcess implements Runnable { public void run() { for(int i = 0; i < 10; i++) { synchronized(MultiThreadExample.stuff) { MultiThreadExample.printFor(i); try { MultiThreadExample.stuff.notifyAll(); MultiThreadExample.stuff.wait(); } catch(InterruptedException ex) { ex.printStackTrace(); } } } } } ```
 Output for code listing 4 ```Thread-1 printing material for the 0 time. Thread-2 printing material for the 0 time. Thread-1 printing material for the 1 time. Thread-2 printing material for the 1 time. Thread-1 printing material for the 2 time. Thread-2 printing material for the 2 time. Thread-1 printing material for the 3 time. Thread-2 printing material for the 3 time. Thread-1 printing material for the 4 time. Thread-2 printing material for the 4 time. Thread-1 printing material for the 5 time. Thread-2 printing material for the 5 time. Thread-1 printing material for the 6 time. Thread-2 printing material for the 6 time. Thread-1 printing material for the 7 time. Thread-2 printing material for the 7 time. Thread-1 printing material for the 8 time. Thread-2 printing material for the 8 time. Thread-1 printing material for the 9 time. Thread-2 printing material for the 9 time. ```

Threads are used intensively in applications that require a considerable amount of CPU usage. For operations that are time-consuming and intensive, it is usually advised to use threads. A example of such an application would be a typical video game. At any given time, a video game involves various characters, objects in the surroundings and other such nuances that needs to be dealt with simultaneously. Dealing with each element or object within the game requires a fair amount of threads to monitor every object.

For example, take this screen-shot of a role-playing strategy game on the right. Here the game visuals depict various in-game characters moving about on the screen. Now imagine processing the movements, direction and behaviors of each of the characters visible on screen. It would certainly take a lot of time moving each character one-by-one if this were to be done one task after another. However if fundamentals of multi-threading are employed, each character would move in a synchronous manner with respect to others.

Threads are not only used heavily in video games, their use is common in everything from simple browser applications to complex operating systems and networking applications. Today it often goes beyond the simple preference of the developer but into the need to maximize the usefulness of contemporaneous hardware that is predicated in heavy multitasking.

References

1. The number of tasks that can be run simultaneously for a single Java application depends on how many tasks an operating system allows to be multithreaded.

Basic Synchronization

In a multi-threaded environment, when more than one thread can access and modify a resource, the outcome could be unpredictable. For example, let's have a counter variable that is incremented by more than one thread.

Beware! Synchronization is an ambiguous term. It doesn't consist of making all threads executing the same code section at the same time. It is the opposite. It prevents any two threads from executing the same code section at the same time. It synchronizes the end of one processing with the beginning of a second processing.

 Code section 1.1: Counter implementation ```int counter = 0; ... counter += 1; ```

The above code is built up by the following sub-operations:

• Read ; read variable `counter`
• Save ; save the new value to variable `counter`

Let's say that two threads need to execute that code, and if the initial value of the `counter` variable is zero, we expect after the operations the value to be 2.

In the above case Thread 1 operation is lost, because Thread 2 overwrites its value. We'd like Thread 2 to wait until Thread 1 finishes the operation. See below:

Critical Section
In the above example the code `counter+=1` must be executed by one and only one thread at any given time. That is called critical section. During programming, in a multi-threading environment we have to identify all those pieces of code that belongs to a critical section, and make sure that only one thread can execute those codes at any given time. That is called synchronization.
The thread access to a critical section code must be synchronized among the threads, that is to make sure that only one thread can execute it at any given time.
Object monitor
Each object has an Object monitor. Basically it is a semaphore, indicating if a critical section code is being executed by a thread or not. Before a critical section can be executed, the thread must obtain an Object monitor. Only one thread at a time can own that object's monitor.
A thread becomes the owner of the object's monitor in one of three ways
• By executing a synchronized instance method of that object. See `synchronized` keyword.
• By executing the body of a synchronized statement that synchronizes on the object. See `synchronized` keyword.
• For objects of type Class, by executing a synchronized static method of that class.
The Object Monitor takes care of the synchronization, so why do we need the "wait() and notify() methods"?
For synchronization we don't really need them, however for certain situations it is nice to use them. A nice and considerate thread will use them. It can happen that during executing a critical section, the thread is stuck, cannot continue. It can be because it's waiting for an IO and other resources. In any case, the thread may need to wait a relatively long time. It would be selfish for the thread to hold on to the object monitor and blocking other threads to do their work. So the thread goes to a 'wait' state, by calling the `wait()` method on the object. It has to be the same object the thread obtained its object monitor from.
On the other hand though, a thread should call the `wait()` method only if there is at least one other thread out there who will call the `notify()` method when the resource is available, otherwise the thread will wait for ever, unless a time interval is specified as parameter.
Let's have an analogy. You go in a shop to buy some items. You line up at the counter, you obtain the attention of the sales-clerk - you get her "object-monitor". You ask for the item you want. One item needs to be brought in from a warehouse. It'll take more than five minutes, so you release the sales-clerk (give her back her "object-monitor") so she can serve other customers. You go into a wait state. Let's say there are five other customers already waiting. There is another sales-clerk, who brings in the items from the warehouse. As she does that, she gets the attention of the first sales-clerk, getting her object-monitor and notifies one or all waiting customer(s), so the waited customer(s) wake up and line up again to get the attention of the first sales-clerk.
Note the synchronization between the waiting customer and the sales-clerk who brings in the items. This is kind of producer-consumer synchronization.
Also note that there is only one object-monitor, belonging to the first sales-clerk. That object-monitor/the attention of clerk needs to be obtained first before a wait and a notify can happen.

`final void wait()` method
The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies the threads waiting on this object's monitor to wake up either through a call to the notify method or to the `notifyAll` method. The thread then waits until it can re-obtain ownership of the monitor and resume execution.
`final void wait(long time)`
The same as wait, but the thread wakes after the specified duration of time passes, regardless of whether there was a notification or not.
`final void notify()`
This method should only be called by a thread that is the owner of this object's monitor. Wakes up a single thread that is waiting on this object's monitor. If many threads are waiting on this object's monitor, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait methods.
The awakened thread will not be able to proceed until the current thread relinquishes the lock on this object. The awakened thread will compete in the usual manner with any other threads that might be actively competing to synchronize on this object; for example, the awakened thread enjoys no reliable privilege or disadvantage in being the next thread to lock this object.
`final void notifyAll()`
Same as `notify()`, but it wakes up all threads that are waiting on this object's monitor.

What are the differences between the sleep() and wait() methods?
`Thread.sleep(millis)`
This is a static method of the Thread class. Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds. The thread does not lose ownership of any monitors. It means that if the thread has an object-monitor, all other threads that need that monitor are blocked. This method can be called regardless whether the thread has any monitor or not.
`wait()`
This method is inherited from the `Object` class. The thread must have obtained the object-monitor of that object first before calling the wait() method. The object monitor is released by the wait() method, so it does not block other waiting threads wanting this object-monitor.

Client Server

In 1990s, the trend was moving away from Mainframe computing to Client/Server as the price of Unix servers dropped. The database access and some business logic were centralized on the back-end server, collecting data from the user program was installed on the front-end users' "client" computers. In the Java world there are three main ways the front-end and the back-end can communicate.

• The client application uses JDBC (Java DataBase Connectivity API) to connect to the data base server, (Limited business logic on the back-end, unless using Stored procedures).
• The client application uses RMI (Remote Method Invocation) to communicate with the back-end.
• The client application uses a socket connection to communicate with the back-end.

Socket Connection Example

Figure 1:Simple Client Server Implementation

Create a Server

The Java language was developed having network computing in mind. For this reason it is very easy to create a server program. A server is a piece of code that runs all the time listening on a particular port on the computer for incoming requests. When a request arrives, it starts a new thread to service the request. See the following example:

Listening on a port

ComServer
class is for listening on a port for a client.
 Code listing 1.1: ComServer ```import java.net.ServerSocket; /** * -- Main Server Class; Listening on a port for client; If there is a client, * starts a new Thread and goes back to listening for further clients. -- */ public class ComServer { static boolean GL_listening = true; /** * -- Main program to start the Server -- */ public static void main(String[] args) throws IOException { ComServer srv = new ComServer(); srv.listen(); } // --- End of Main Method --- /** * -- Server method; Listen for client -- */ public int listen() throws IOException { ServerSocket serverSocket = null; int iPortNumber = 9090; // --- Open the Server Socket where this should listen --- try { System.out.println( "*** Open the listening socket; at:"+ iPortNumber + " ***" ); serverSocket = new ServerSocket( iPortNumber ); } catch (IOException e) { System.err.println("Could not listen on port:"+iPortNumber ); System.exit(1); } while ( GL_listening ) { ComServerThread clientServ; // --- Listening for client; If there is a client start a Thread - System.out.println( "*** Listen for a Client; at:"+ iPortNumber + " ***" ); clientServ = new ComServerThread( serverSocket.accept() ); // --- Service a Client --- System.out.println( "*** A Client came; Service it ***" ); clientServ.start(); /* --- Use for multy Threaded --- */ // clientServ.run(); /* --- Use for Single Threaded --- */ } // --- Close the Server socket; Server exiting --- serverSocket.close(); return 0; } // --- End of listen Method --- } // --- End of ComServer Class --- ```
ServerSocket( iPortNumber )
Creates a server socket, bound to the specified port.
serverSocket.accept()
Listens for a connection to be made to this socket and accepts it. The method blocks until a connection is made. It returns a new Socket.

Service One Client

This class extended from a Thread is responsible to service one client. The Socket connection will be open between the client and server. A simple protocol has to be defined between the client and server, the server has to understand what the client wants from the server. The client will send a terminate command, for which the server will terminate the socket connection. The ComServerThread class is responsible to handle all client requests, until the client sends a terminate command.
 Code listing 1.2: ComServerThread ``` /** * -- A class extended from a Thread; Responsible to service one client -- */ class '''ComServerThread''' extends Thread { private Socket clientSocket = null; COM_DATA tDataFromClient; COM_DATA tDataToClient; ObjectInputStream oIn; ObjectOutputStream oOut; /** * -- Constructor -- */ public ComServerThread( Socket socket ) { super( "ComServerThread" ); this.clientSocket = socket; } // -- End of ComServerThread() constructor -- /** * -- Overrun from the Thread (super) class -- */ public void run() { try { // --- Create the Writer; will be used to send data to client --- oOut = new ObjectOutputStream( clientSocket.getOutputStream() ); // --- Create the Reader; will be used to get data from client --- oIn = new ObjectInputStream( clientSocket.getInputStream() ); // --- Create a new protocol object --- ComProtocol comp = new ComProtocol(); // --- Send something to client to indicate that server is ready --- tDataToClient = '''comp.processInput( null );''' '''sendDataToClient'''( tDataToClient, oOut ); // --- Get the data from the client --- while ( true ) { try { tDataFromClient = '''getDataFromClient( oIn )'''; // --- Parse the request and get the reply --- tDataToClient = '''comp.processInput( tDataFromClient );''' // --- Send data to the Client --- '''sendDataToClient'''( tDataToClient, oOut ); } catch ( EOFException e ) { System.out.println( "Client Disconnected, Bye, Bye" ); break; } // --- See if the Client wanted to terminate the connection --- if ( tDataToClient.bExit ) { System.out.println( "Client said Bye. Bye" ); break; } } // --- Close resources; This client is gone --- comp.Final(); oOut.close(); oIn.close(); clientSocket.close(); } catch ( IOException e ) { e.printStackTrace(); } } // -- End of run() Method -- /** * Get data from Client */ private static COM_DATA '''getDataFromClient'''( ObjectInputStream oIn ) throws IOException { COM_DATA tDataFromClient = null; // --- Initialize variables --- // tDataFromClient = new COM_DATA(); while ( tDataFromClient == null ) { try { // --- Read Line Number first -- tDataFromClient = (COM_DATA) oIn.readObject(); } catch ( ClassNotFoundException e ) { System.out.println( "ClassNotFound" ); } } System.out.println( "Get: " + tDataFromClient.comData ); return tDataFromClient; } // --- getDataFromClient() Method --- /** * Send data to Client */ private static void '''sendDataToClient'''( COM_DATA tDataToClient, ObjectOutputStream oOut ) throws IOException { System.out.println( "Sent: " + tDataToClient.comData ); oOut.writeObject( tDataToClient ); return; } // -- End of sendDataToClient() Method -- } // --- End of ComServerThread class --- ```
COM_DATA tDataFromClient
This variable will contain the data object from the client.
COM_DATA tDataToClient
This variable will contain the data object to be sent to the client.
sendDataToClient
This method sends the data object to the client.
getDataFromClient
This method gets the data object from the client.
processInput( tDataFromClient )
This method of the class `ComProtocol` interprets the client commands and returns the data object that will be sent back to the client.

Handling the request; implements the communication protocol

ComProtocol
This class implements, and encapsulates the communication logic (protocol). The protocol is the following:
1. The client initiate the connection.
2. The server accepts it and sends an acknowledgment notifying that it's ready
3. The client sends a request
4. The server response based on the request
...
1. The client sends a `BYE` request
2. The server acknowledge the `BYE` request and disconnects the socket connection
3. The client gets the acknowledgment to the `BYE`
...
1. The client sends a `SHUTDOWN` request
2. The server acknowledge the `SHUTDOWN` request and disconnects and also stops listening of other clients.
3. The client gets the acknowledgment to the `SHUTDOWN`
 Code listing 1.3: ComProtocol ``` class '''ComProtocol''' { private static final int COM_STATUS_WAITING = 0; private static final int COM_STATUS_READY_SENT = 1; private static final int COM_STATUS_DATA_SENT = 2; private static final int COM_STATUS_WAITING_FOR_TERMINALID = 3; private int state = COM_STATUS_WAITING; // --- Reference to 'BACK-END' module --- private MqTeAccess mqTe; ... /** * Create a protokol object; CAll MQ INI function */ public ComProtocol() { int iRet = 0; // --- Initialize 'BACK-END' modules --- mqTe. ... ... } /** * --- Process the Input and Create the output to the Client --- */ public COM_DATA processInput( COM_DATA theInput ) { COM_DATA theOutput; // --- Initialize Variables --- theOutput = new COM_DATA(); // --- Check if the Clients want to disconnect --- if ( theInput != null ) { if ( theInput.comData.equals('''"!BYE.@"''') ) { // --- The Client wants to terminate; Echo data back to client theOutput.comData = "BYE."; // --- Mark the communication to be terminated --- theOutput.bExit = true; // --- Set the internal state to wait for a new client --- state = COM_STATUS_WAITING; // --- Return Data object to be sent to the client --- return theOutput; } if ( theInput.comData.equals('''"!SHUTDOWN.@"''') ) { // --- The Client wants to terminate; Echo data back to client theOutput.comData = "BYE."; // --- Mark the communication to be terminated --- theOutput.bExit = true; // --- Tell the server to stop listening for new clients --- ComServer.GL_listening = false; // --- Set the internal state to wait for a new client --- state = COM_STATUS_WAITING; // --- Return Data object to be sent to the client --- return theOutput; } } if ( state == COM_STATUS_WAITING ) { // --- Send ready Message to the Client --- theOutput.comData = "Ready:"; // --- Set the internal state ready; and wait for TerminalId --- state = COM_STATUS_WAITING_FOR_TERMINALID; } else if ( state == COM_STATUS_WAITING_FOR_TERMINALID ) { int iRet; // --- Get the Terminal ID --- sTermId = theInput.comData; // --- Call 'BACK-END' modules ... --- mqTe. ... ... // --- Send ready Message with the Server Version to the Client --- theOutput.comData = "Ready;Server Version 1.0:"; // --- Set the internal state raedy; and wait for TerminalId --- state = COM_STATUS_READY_SENT; } else if ( state == COM_STATUS_READY_SENT ) { int iRet; String sCommand = theInput.comData; // --- Call 'BACK-END' modules ... ... /* ** --- Check if we should get Response data --- */ if ( theInput.iRet == COM_DATA.NOWAIT_FOR_RESPONSE ) { // -- Set the Output Value --- theOutput.iRet = iRet; theOutput.comData = ""; } else { // --- Call 'BACK-END' modules --- mqTe. ... // --- Set the Output Value --- theOutput.comData = mqTe.sResponseBuffer; theOutput.iRet = iRet; } } return theOutput; } // --- End of Method processInput() --- } // --- End of ComProtocol Class Definition --- ---- ```

The Data object that goes through the network

COM_DATA
is data structure class that is transmitted through the network. The class contains only data.
 Code listing 1.4: COM_DATA ``` /** * COM_DATA data structure */ public class COM_DATA implements Serializable { public String comData; public boolean bExit; public int iRet; /** * --- Constants values can be passed in in iRet to the Server --- */ static final int WAIT_FOR_RESPONSE = 0; static final int NOWAIT_FOR_RESPONSE = 1; /** * Initialize the data structure */ public COM_DATA() { comData = ""; bExit = false; iRet = 0; } // -- End of COM_DATA() Constructor -- /** * Copy over it contents */ public void copy( COM_DATA tSrc ) { this.comData = tSrc.comData; this.bExit = tSrc.bExit; this.iRet = tSrc.iRet; return; } } // -- End of COM_DATA class -- ```

Create the Client

A client code for a server/service is usually an API that a user application uses to interface to the server. With the help of a client API the user application does not have to know how to connect to the server to get services.

ComClient
This class is the client API. The application is using this class to communicate with the server.

The following is the client class for the above server:

 Code listing 1.5: ComClient ``` public class ComClient { private Socket comSocket; private ObjectOutputStream oOut; private ObjectInputStream oIn; private boolean IsItOpen = false; /** * --- Open Socket --- */ public void openCom( String sServerName, int iPortNumber ) throws UnknownHostException, IOException { try { // --- Open Socket for communication --- comSocket = new Socket( sServerName, iPortNumber ); // --- Get Stream to write request to the Server --- oOut = new ObjectOutputStream( comSocket.getOutputStream() ); // --- Get Stream// to read from the Server oIn = new ObjectInputStream( comSocket.getInputStream()); // --- Set internal Member variable that the Communication opened --- IsItOpen = true; } catch ( java.net.UnknownHostException e ) { System.err.println( "(openCom:)Don't know about host: "+sServerName ); IsItOpen = false; throw( e ); } catch ( java.io.IOException e ) { System.err.println("(openCom:)Couldn't get I/O for the connection to: "+ sServerName ); IsItOpen = false; throw( e ); } } /** * --- Check if Socket is open --- */ public boolean isItOpen() { return IsItOpen; } /** * --- Get data string from the Server --- */ public void getServerData( COM_DATA tServData ) throws IOException { // --- Initialize Variables --- tServData.comData = ""; // --- Get the Response from the Server --- try { tServData.copy( (COM_DATA) oIn.readObject() ); } catch ( ClassNotFoundException e ) { System.out.println( "Class Not Found" ); } System.out.println( "Server: " + tServData.comData ); if ( tServData.comData.equals("BYE.") ) { tServData.bExit = true; } return; } /** * --- Send data to the Server --- */ public void sendDataToServer( COM_DATA tServData ) throws IOException { // --- Send the data string --- System.out.println( "Send: " + tServData.comData ); oOut.writeObject( tServData ); return; } /** * --- Close Socket --- */ public void closeCom() throws IOException { oOut.close(); oIn.close(); comSocket.close(); IsItOpen = false; } } ```
getServerData( COM_DATA tServData )
This method reads the data from the server and copies the values to `tServData` object.
sendDataToServer( COM_DATA tServData )
This method sends the `tServData` object through the network to the server.
This method returns the data object sent by the server.
oOut.writeObject( tServData )
This method sends the data object to the server.

Remote Method Invocation

Java's Remote Method Invocation (commonly referred to as RMI) is used for client and server models. RMI is the object oriented equivalent to RPC (Remote procedure call).

The Java Remote Method Invocation (RMI) system allows an object running in one Java Virtual Machine (VM) to invoke methods of an object running in another Java VM. RMI provides for remote communication between programs written in the Java programming language.

RMI is only defined for use with the Java platform. If you need to call methods between different language environments, use CORBA. With CORBA a Java client can call a C++ server and/or a C++ client can call a Java server. With RMI that can not be done.

STUB and SKELETON

The remote method invocation goes through a STUB on the client side and a so called SKELETON on the server side.

```CLIENT --> STUB --> ... Network ... --> SKELETON --> REMOTE OBJECT
```

Prior to Java 1.2 the skeleton had to be explicitly generated with the rmic tool. Since 1.2 a dynamic skeleton is used, which employs the features of Java Reflection to do its work.

rmiregistry

Remote objects can be listed in the RMI Registry. Clients can get a reference to the remote object by querying the Registry. After that, the client can call methods on the remote objects. (Remote object references can also be acquired by calling other remote methods. The Registry is really a 'bootstrap' that solves the problem of where to get the initial remote reference from.)

The RMI Registry can either be started within the server JVM, via the LocateRegistry.createRegistry() API, or a separate process called rmiregistry that has to be started before remote objects can be added to it, e.g. by the command line in Unix:

 rmiregistry on Unix ```rmiregistry & ```

or under Windows:

 rmiregistry on Windows ```start rmiregistry ```

If port is not specified the default 1099 is used. The client will need to connect to this port to access the Registry.

The Registry can also be started from a program by calling the following code:

 Code section 1: rmiregistry starting ```import java.rmi.registry.LocateRegistry; ... Registry reg = LocateRegistry.createRegistry(iPort); ```

Objects passed in as parameters to the remote objects's methods will be passed by value. If the remote object changes the passed-in object values, it won't be reflected on the client side, this is opposite what happens when a local object is called. Objects that used as parameters for remote methods invocation must implement the `java.io.Serializable` interface, as they are going to be serialized when passed through the network, and a new object will be created on the other side.

However, exported remote objects passed as parameters are passed by remote reference.

RMI Remote object

The remote object has to either extend the `java.rmi.server.UnicastRemoteObject` object, or be explicitly exported by calling the `java.rmi.server.UnicastRemoteObject.exportObject()` method.

RMI clients

Here is an example of RMI client:

 Code listing 7.10: HelloClient.java ``` 1 import java.rmi.registry.LocateRegistry; 2 import java.rmi.registry.Registry; 3 4 public class HelloClient{ 5 6 private HelloClient() {} 7 8 public static void main(String[] args) { 9 String host = (args.length < 1) ? null : args[0]; 10 try { 11 Registry registry = LocateRegistry.getRegistry(host); 12 Hello stub = (Hello) registry.lookup("Hello"); 13 String response = stub.sayHello(); 14 System.out.println("response: " + response); 15 } catch (Exception e) { 16 System.err.println("Client exception: " + e.toString()); 17 e.printStackTrace(); 18 } 19 } 20 } ```

EJB

Enterprise JavaBeans (EJB) technology is the server-side component architecture for Java Platform, Enterprise Edition (Java EE). EJB technology enables to create distributed, transactional, secure and portable application component objects.

EJB supports the development and deployment of component based business applications. Applications written using the Enterprise JavaBeans architecture are scalable, transactional, and multi-user secure. These applications may be written once, and then deployed on any server platform that supports the Enterprise JavaBeans specification.

EJB Features

• Security Management
• Persistence Management
• Transaction Management
• Distributable Interoperable Management
• Exception Management

Types of EJB

• Session Beans
• StateFull Session Beans
• Stateless Session Beans
• Entity Beans
• Message Driven Beans

Problems with EJB as a component based development

EJBs are an attempt to create component based application development. With EJBs it is easier to develop components, but the same basic and fundamental maintenance problem will still be there. That is the dependencies between the client and the components. The usage of a component is fixed, changes on the component interface cause to break the client code. The same client/server problem comes back, that is as the users of a component increases the maintenance of that component getting harder and harder until it goes to impossible.

For a true component based application development we need to standardize the usage of a component. The client must somehow flexibly figure out automatically how to use a component, so component changes don't affect any of the clients using that component. Without that flexibility, a true component based application development will remain as an idea, a dream, a theory without significant practical use. If we had that flexibility, it could cause a paradigm shift in the software development industry.

JINI was an attempt from Sun to address this flexibility problem. In JINI, the client download the component interface implementation and execute it in the client space.

So we need to mix (somehow) EJB and JINI technologies to come up with a true flexible component based technology.