Today was day four of our Java training, we looked at generics, collection and IO today, here is what was covered

The Collections Framework

Legacy Container Classes

A container is an object that holds a collection of other objects

An array is a simple container. Arrays have a couple of limitations

. The size is fixed

. All the members of the array must be of the same type

. You can’t add methods and attributes to an array

The java.util package has two container classes as well as an supporting interface

Vector class

Has add() and remove() methods, the elementAt() method let’s you retrieve an element at a specified index

The Stack subclass provides the push() and pop() methods, this will support a LIFO stack

Hashtable class

This is an expandable associative array

The entries are stored as key/value pairs, no dups allowed

The Properties subclass will hold the name/value pairs

The Enumeration interface can be used to traverse either the vector or the hashtable objects. Enumeration has hasMoreElements() and nextElements() methods

Legacy Container Classes Disadvantages

It is not type safe, the containers can hold any kind of objects

The references must be downcast explicitly if you want to access the objects

They are synchronized, performance hit

Code needs to be rewritten if you want to replace one container with a container from another type

Vector, Hashtable and the Enumeration interface in Java SE 5+

Vector, Hashtable and the Enumeration interface have been redefined as generics

Vector is now Vector and it implements the List> interface

Hashtable is now Hashtable and implements the Map interface

Enumeration is now Enumeration .

Enumeration has been superseded by the Iterator interface

The enhanced for loop (or for each loop) works automatically with the generic versions of the containers

Collections Framework

The Collections Framework is a unified framework fo manipulating collections of objects

Programmers can choose from a variety of structures

The collections framework consists of:

  • Collection Interfaces – Represent different types of collections, such as sets, lists and maps. These interfaces form the basis of the framework.
  • General-purpose Implementations – Primary implementations of the collection interfaces.
  • Legacy Implementations – The collection classes from earlier releases, Vector and Hashtable, have been retrofitted to implement the collection interfaces.
  • Special-purpose Implementations – Implementations designed for use in special situations. These implementations display nonstandard performance characteristics, usage restrictions, or behavior.
  • Concurrent Implementations – Implementations designed for highly concurrent use.

    Wrapper Implementations – Add functionality, such as synchronization, to other implementations.

  • Convenience Implementations – High-performance “mini-implementations” of the collection interfaces.

  • Abstract Implementations – Partial implementations of the collection interfaces to facilitate custom implementations.

  • Algorithms – Static methods that perform useful functions on collections, such as sorting a list.

  • Infrastructure – Interfaces that provide essential support for the collection interfaces.

  • Array Utilities – Utility functions for arrays of primitives and reference objects. Not, strictly speaking, a part of the Collections Framework, this functionality was added to the Java platform at the same time and relies on some of the same infrastructure.

Collection Implementations

The general purpose implementations are summarized in the table below:

Hash Table Resizable Array Balanced Tree Linked List Hash Table + Linked List
Interfaces Set HashSet   TreeSet   LinkedHashSet
List   ArrayList   LinkedList  
Deque   ArrayDeque   LinkedList  
Map HashMap   TreeMap   LinkedHashMap

Code to the interface, not to the class, you can now change the container without having to make code changes

ArrayList<Integer>   list  = new ArrayList<Integer>();
LinkedList<Integer>  list =  new LinkedList<Integer>();
List<Integer> list  = new ArrayList<Integer>();
List<Integer> list =  new LinkedList<Integer>();

There is a tutorial availabe on the Oracle website here:



Inefficient, checks must be done even if stuff doesn’t blow up

Difficult to maintain

Using a return value as both an output value and an error status is confusing

Compiler does not enforce error checking

Using Exceptions

Compiler can enforce proper exception handling

Exception is caught by a block designed to handle the exception

Errors cause by constructors, initializers and other code that doesn’t return a return value

All exceptions objects are subclasses of java.lang.Throwable and they inherit its methods

Error, Exception and RuntimeException are treated differently by the compiler

Error, this mean as major system-level error occured

RuntimeException , logic or data validateion error that should have been found and fixed during development

Exception, run-time problems like a file that can’t be found or a network problem

A program can catch exceptions by using a combination of the try, catch, and finally blocks.

The try block identifies a block of code in which an exception can occur.

The catch block identifies a block of code, known as an exception handler, that can handle a particular type of exception.

The finally block identifies a block of code that is guaranteed to execute, and is the right place to close files, recover resources, and otherwise clean up after the code enclosed in the try block.


This was added in Java 1.4, it is a simple way to check run-time conditions and throw exceptions when you are debugging code

It can be enabled or disabled at runtime, by default they are disabled, use the -ea switch from the command line to enable it. Since Java doesn’t have a preprocessor this would be a way to do testing without having to modify the code


We looked at IO and the different IO classes to work with files, streams sockets etc etc

Here is a list of the I/O Streams

Byte Streams

handle I/O of raw binary data.

Character Streams

handle I/O of character data, automatically handling translation to and from the local character set.

Buffered Streams

optimize input and output by reducing the number of calls to the native API.

Scanning and Formatting

allows a program to read and write formatted text.

I/O from the Command Line

describes the Standard Streams and the Console object.

Data Streams

handle binary I/O of primitive data type and String values.

Object Streams

handle binary I/O of objects.

That is all for today