You are on page 1of 126

Java Seminar

Write Once, Run Anywhere

Brief History of Java


Java started off as a research project Research efforts birthed a new language, OAK

Java was publicly released May 27, 1995

Java - General

Java programming language


The one we use to write our program Compiled to byte code of JVM

Java virtual machine (JVM)


Java interpreter interpret the compiled byte code Cross-platform: support Linux, Windows, PalmOSetc.

Java runtime environment (JRE)


Predefined set of java classes available to use Core Java APIs basic utilities, I/O, graphics, network

Java - General

Java has some interesting features:


automatic type checking, automatic garbage collection, simplifies pointers; no directly accessible pointer to memory, simplified network access, multi-threading!

How it works!
Compile-time Environment Compile-time Environment
Class Loader Java Source (.java) Java Bytecodes move locally or through network Bytecode Verifier Java Class Libraries

Java Interpreter

Just in Time Compiler

Java Compiler

Java Virtual machine

Runtime System

Java Bytecode (.class )

Operating System

Hardware

Object-Oriented

Java supports OOD


Polymorphism Inheritance Encapsulation

Java programs contain nothing but definitions and instantiations of classes


Everything is encapsulated in a class!

Java Advantages

Portable - Write Once, Run Anywhere Security has been well thought through Robust memory management Designed for network programming Multi-threaded (multiple simultaneous tasks) Dynamic & extensible (loads of libraries)
Classes stored in separate files Loaded only when needed

Basic Java Syntax

Primitive Types and Variables


boolean, char, byte, short, int, long, float, double etc. These basic (or primitive) types are the only types that are not objects (due to performance issues). This means that you dont use the new operator to create a primitive variable. Declaring primitive variables:
float initVal; int retVal, index = 2; double gamma = 1.2, brightness boolean valueOk = false;

Initialisation

If no value is assigned prior to use, then the compiler will give an error Java sets primitive variables to zero or false in the case of a boolean variable All object references are initially set to null An array of anything is an object Set to null on declaration Elements to zero false or null on creation

Declarations
int index = 1.2; // compiler error boolean retOk = 1; // compiler error double fiveFourths = 5 / 4; // no error! float ratio = 5.8f; // correct double fiveFourths = 5.0 / 4.0; // correct

1.2f is a float value accurate to 7 decimal places. 1.2 is a double value accurate to 15 decimal places.

Basic Mathematical Operators

* / % + - are the mathematical operators * / % have a higher precedence than + or -

double myVal = a + b % d c * d / b;
Is the same as: double myVal = (a + (b % d)) ((c * d) / b);

Statements & Blocks

A simple statement is a command terminated by a semi-colon: name = Fred; A block is a compound statement enclosed in curly brackets: { name1 = Fred; name2 = Bill; } Blocks may contain other blocks

Flow of Control

Java executes one statement after the other in the order they are written Many Java statements are flow control statements: Alternation: if, if else, switch Looping: for, while, do while Escapes: break, continue, return

If The Conditional Statement

The if statement evaluates an expression and if that evaluation is true then the specified action is taken
if ( x < 10 ) x = 10;

If the value of x is less than 10, make x equal to 10 It could have been written:
if ( x < 10 ) x = 10;

Or, alternatively:
if ( x < 10 ) { x = 10; }

Relational Operators
== != >= <= > < Equal (careful) Not equal Greater than or equal Less than or equal Greater than Less than

If else

The if else statement evaluates an expression and performs one action if that evaluation is true or a different action if it is false. if (x != oldx) {
System.out.print(x was changed);
} else { System.out.print(x is unchanged); }

Nested if else
if ( myVal > 100 ) { if ( remainderOn == true) { myVal = mVal % 100; } else { myVal = myVal / 100.0; } } else { System.out.print(myVal is in range); }

else if

Useful for choosing between alternatives:


if ( n == 1 ) { // execute code block #1 } else if ( j == 2 ) { // execute code block #2 } else { // if all previous tests have failed, execute code block #3 }

A Warning
WRONG! if( i == j )
if ( j == k ) System.out.print( i equals k); else System.out.print( i is not equal to j);

CORRECT! if( i == j ) { if ( j == k ) System.out.print( i equals k); } else System.out.print( i is not equal to j); // Correct!

The switch Statement


switch ( n ) { case 1: // execute code block #1 break; case 2: // execute code block #2 break; default: // if all previous tests fail then //execute code block #4 break; }

The for loop

Loop n times for ( i = 0; i < n; n++ ) { // this code body will execute n times // ifrom 0 to n-1 } Nested for: for ( j = 0; j < 10; j++ ) { for ( i = 0; i < 20; i++ ){ }
}

while loops
while t r n } (n > 0){ = n % 10; = r * 10 + t; = n / 10;

do { } while loops
do{
t = n % 10; r = r * 10 + t; n = n / 10; }while (n > 0); What is the minimum number of times the loop is executed? What is the maximum number of times?

Break

A break statement causes an exit from the innermost containing while, do, for or switch statement.
for ( int i = 0; i < maxID, i++ ) { if ( userID[i] == targetID ) { index = i; break; } } // program jumps here after break

Continue

Can only be used with while, do or for. The continue statement causes the innermost loop to start the next iteration immediately
for ( int i = 0; i < maxID; i++ ) { if ( userID[i] != -1 ) continue; System.out.print( UserID + i + : + userID); }

Arrays

Am array is a list of similar things An array has a fixed: name type length These must be declared when the array is created. Arrays sizes cannot be changed during the execution of the code

myArray =

3
0

6
1

3
2

1
3

6
4

3
5

4
6

1
7

myArray has room for 8 elements the elements are accessed by their index in Java, array indices start at 0

Declaring Arrays
int myArray[]; declares myArray to be an array of integers myArray = new int[8]; sets up 8 integer-sized spaces in memory, labelled myArray[0] to myArray[7] int myArray[] = new int[8]; combines the two statements in one line

Assigning Values

refer to the array elements by index to store values in them. myArray[0] = 3; myArray[1] = 6; myArray[2] = 3; ... can create and initialise in one step: int myArray[] = {3, 6, 3, 1, 6, 3, 4, 1};

Iterating Through Arrays

for loops are useful when dealing with arrays:


for (int i = 0; i < myArray.length; i++) { myArray[i] = getsomevalue(); }

Arrays of Objects

So far we have looked at an array of primitive types. integers could also use doubles, floats, characters Often want to have an array of objects Students, Books, Loans Need to follow 3 steps.

Declaring the Array


1. Declare the array private Student studentList[]; this declares studentList

2 .Create the array


studentList = new Student[10]; this sets up 10 spaces in memory that can hold references to Student objects 3. Create Student objects and add them to the array: studentList[0] = new

Student("Cathy", "Computing");

Java Methods & Classes

Classes ARE Object Definitions


OOP - object oriented programming code built from objects Java these are called classes Each class definition is coded in a separate .java file Name of the object must match the class/object name

The three principles of OOP

Encapsulation
Objects hide their functions (methods) and data (instance variables)

Inheritance
Each subclass inherits all variables of its manual superclass

car

Super class
automatic

Subclasses

Polymorphism
Interface same despite draw() different data types

draw()

Simple Class and Method


Class Fruit{ int grams; int cals_per_gram; int total_calories() { return(grams*cals_per_gram); } }

Methods

A method is a named sequence of code that can be invoked by other Java code. A method takes some parameters, performs some computations and then optionally returns a value (or object). Methods can be used as part of an expression statement.
public float convertCelsius(float tempC) { return( ((tempC * 9.0f) / 5.0f) + 32.0 ); }

Method Signatures

A method signature specifies:


The name of the method. The type and name of each parameter. The type of the value (or object) returned by the method. The checked exceptions thrown by the method. Various method modifiers. modifiers type name ( parameter list ) [throws exceptions ] public float convertCelsius (float tCelsius ) {} public boolean setUserInfo ( int i, int j, String name ) throws IndexOutOfBoundsException {}

Public/private

Methods/data may be declared public or private meaning they may or may not be accessed by code in other classes Good practice:
keep data private keep most methods private

well-defined interface between classes helps to eliminate errors

Using objects

Here, code in one class creates an instance of another class and does something with it
Fruit plum=new Fruit(); int cals; cals = plum.total_calories();

Dot operator allows you to access (public) data/methods inside Fruit class

Constructors

The line
plum = new Fruit();

invokes a constructor method with which you can set the initial data of an object You may choose several different type of constructor with different argument lists
eg Fruit(), Fruit(a) ...

Overloading

Can have several versions of a method in class with different types/numbers of arguments
Fruit() {grams=50;} Fruit(a,b) { grams=a; cals_per_gram=b;}

By looking at arguments Java decides which version to use

Abstract Classes
Subclasses of an abstract class must implement all abstract methods, or they too must be declared to be abstract Advantages
Can still use superclass reference to access all subclass objects in polymorphic way
However, we need to declare the methods we will need in the superclass, even if they are abstract

No need to specifically define common data and methods for each subclass - it is inherited Helps to organize class hierarchy

See ex23.java Lets look at MusicCD and CompilationCD again too

Interfaces

Java allows only single inheritance


A new class can be a subclass of only one parent (super) class There are several reasons for this, from both the implementation (i.e. how to do it in the compiler and interpreter) point of view and the programmer (i.e. how to use it effectively) point of view However, it is sometimes useful to be able to access an object through more than one superclass reference

Interfaces
We may want to identify an object in multiple ways:
One based on its inherent nature (i.e. its inheritance chain)
Ex: A Person

Others based on what it is capable of doing


Ex: An athlete Ex: a pilot

Interfaces is a named set of A Java interface


methods
However, no method bodies are given just the headers Static constants are allowed, but no instance variables are allowed No static methods are allowed

Any Java class (no matter what its inheritance) can implement an interface by implementing the methods defined in it A given class can implement any number of interfaces

Interfaces Ex:
public interface Laughable { public void laugh(); } public interface Booable { public void boo(); }

Any Java class can implement Laughable by implementing the method laugh() Any Java class can implement Booable by implementing the method boo()

Interfaces

Ex:
public class Comedian implements Laughable, Booable { // various methods here (constructor, etc.) public void laugh() { System.out.println(Ha ha ha); } public void boo() { System.out.println(You stink!); } }

An interface variable can be used to reference any object that implements that interface
Note that the same method name (ex: laugh() below) may in fact represent different code segments in different classes Also, only the interface methods are accessible through the interface reference

Interfaces

Ex:
Laughable L1, L2, L3; L1 = new Comedian(); L2 = new SitCom(); // implements Laughable L3 = new Clown(); // implements Laughable L1.laugh(); L2.laugh(); L3.laugh();

Interfaces
Polymorphism and Dynamic Binding also apply to interfaces
the interface acts as a superclass and the implementing classes implement the actual methods however they want

An interface variable can be used to reference any object that implements that interface
However, only the interface methods are accessible through the interface reference

Recall our previous example:

Laughable [] funny = new Laughable[3]; funny[0] = new Comedian(); funny[1] = new SitCom(); // implements Laughable funny[2] = new Clown(); // implements Laughable for (int i = 0; i < funny.length; i++) funny[i].laugh();

See ex24.java

Exception-Handling Fundamentals

An exception is an abnormal condition that arises in a code sequence at run time A Java exception is an object that describes an exceptional condition that has occurred in a piece of code When an exceptional condition arises, an object representing that exception is created and thrown in the method that caused the error An exception can be caught to handle it or pass it on Exceptions can be generated by the Java runtime system, or they can be manually generated by your code 52

Exception-Handling Fundamentals

Java exception handling is managed by via five keywords: try, catch, throw, throws, and finally Program statements to monitor are contained within a try block If an exception occurs within the try block, it is thrown Code within catch block catch the exception and handle it System generated exceptions are automatically thrown by the Java run-time system To manually throw an exception, use the keyword throw Any exception that is thrown out of a method must 53 be specified as such by a throws clause

Exception-Handling Fundamentals

Any code that absolutely must be executed before a method returns is put in a finally block General form of an exception-handling block
try{

// block of code to monitor for errors


} catch (ExceptionType1 exOb){ // exception handler for ExceptionType1 } catch (ExceptionType2 exOb){ // exception handler for ExceptionType2 } // finally{ // block of code to be executed before try block ends

54

Exception Types

All exception types are subclasses of the built-in class Throwable Throwable has two subclasses, they are
Exception (to handle exceptional conditions that user programs should catch)
An important subclass of Exception is RuntimeException, that includes division by zero and invalid array indexing

Error (to handle exceptional conditions that are not expected to be caught under normal circumstances). i.e. stack overflow
55

Uncaught Exceptions

If an exception is not caught by user program, then execution of the program stops and it is caught by the default handler provided by the Java run-time system Default handler prints a stack trace from the point at which the exception occurred, and terminates the program

Ex:
class Exc0 { public static void main(String args[]) { int d = 0; int a = 42 / d; } }

Output:
java.lang.ArithmeticException: / by zero at Exc0.main(Exc0.java:4)
56

Exception in thread "main"

Using try and catch

Handling an exception has two benefits,


It allows you to fix the error It prevents the program from automatically terminating

The catch clause should follow immediately the try block Once an exception is thrown, program control transfer out of the try block into the catch block Once the catch statement has executed, program control continues with the next line in the program following the entire try/catch 57 mechanism

Example

Output:
Division by zero. After catch statement.
58

Using try and catch


A try and catch statement form a unit. The scope of the catch clause is restricted to those statements specified by the immediately preceding try statement You cannot use try on a single statement

59

Multiple catch Clauses


If more than one can occur, then we use multiple catch clauses When an exception is thrown, each catch statement is inspected in order, and the first one whose type matches that of the exception is executed After one catch statement executes, the others are bypassed

60

Example

61

Example (Cont.)

If no command line argument is provided, then you will see the following output:
a=0 Divide by 0: java.lang.ArithmeticException: / by zero After try/catch blocks

If any command line argument is provided, then you will see the following output:
a=1 62 Array index oob: java.lang.ArrayIndexOutOfBoundsException

Caution

Remember that, exception subclass must come before any of of their superclasses Because, a catch statement that uses a superclass will catch exceptions of that type plus any of its subclasses. So, the subclass would never be reached if it come after its superclass For example, ArithmeticException is a subclass of Exception Moreover, unreachable code in Java generates error

63

Example

64

Nested try Statements

A try statement can be inside the block of another try Each time a try statement is entered, the context of that exception is pushed on the stack If an inner try statement does not have a catch, then the next try statements catch handlers are inspected for a match If a method call within a try block has try block within it, then then it is still nested try

65

Example

66

Output

When no parameter is given:


Divide by 0: java.lang.ArithmeticException: / by zero

When one parameter is given


a=1 Divide by 0: java.lang.ArithmeticException: / by zero

When two parameters are given


a=2 Array index out-of-bounds: java.lang.ArrayIndexOutOfBoundsException

67

throw

It is possible for your program to to throw an exception explicitly

throw TrrowableInstance Here, TrrowableInstance must be an object of type Throwable or a subclass Throwable There are two ways to obtain a Throwable objects:
Using a parameter into a catch clause Creating one with the new operator
68

Example

Output:
Caught inside demoproc. Recaught: java.lang.NullPointerException: demo
69

throws

If a method is capable of causing an exception that it does not handle, it must specify this behavior so that callers of the method can guard themselves against that exception
type method-name parameter-list) throws exception-list { // body of method }

It is not applicable for Error or RuntimeException, or any of their subclasses

70

Example: incorrect program

71

Example: corrected version

Output: Inside throwOne. Caught java.lang.IllegalAccessException: demo


72

finally
It is used to handle premature execution of a method (i.e. a method open a file upon entry and closes it upon exit) finally creates a block of code that will be executed after try/catch block has completed and before the code following the try/catch block finally clause will execute whether or not an exception is thrown

73

Example

74

Output
inside procA procA's finally Exception caught inside procB procB's finally inside procC procC's finally
75

Javas Built-in Errors

Small letter indicate package name

Capital letter indicate class name

76

Javas Built-in Exceptions

77

Garbage collector

In C++, you have to make sure that you destroy the objects when you are done with them.
Otherwise, memory leak.

In Java, garbage collector do it for you.


It looks at all the objects created by new and figure out which ones are no longer being referenced. Then it release the memory for those objects.

What are Threads?

A piece of code that run in concurrent with other threads. Each thread is a statically ordered sequence of instructions. Threads are being extensively used express concurrency on both single and multiprocessors machines. Programming a task having multiple threads of control Multithreading or Multithreaded 79 Programming.

Java Threads

Java has built in thread support for Multithreading Synchronization Thread Scheduling Inter-Thread Communication:

80

currentThread yield sleep resume

start run stop

setPriority getPriority suspend

Java Garbage Collector is a low-priority thread.

Threading Mechanisms...
Create

a class that extends the Thread class Create a class that implements the Runnable interface
Thread MyThread Runnable MyClass Thread

(objects are threads) (objects with run() body) [a]


81

[b]

1st method: Extending Thread class

Create a class by extending Thread class and override run() method:


class MyThread extends Thread { public void run() { // thread body of execution } }

Create a thread: MyThread thr1 = new MyThread(); Start Execution of threads: thr1.start(); Create and Execute: new MyThread().start();

82

An example
class MyThread extends Thread { public void run() { System.out.println(" this thread is running ... "); } }
class ThreadEx1 { public static void main(String [] args ) { MyThread t = new MyThread(); t.start(); } }

83

2nd method: Threads by implementing Runnable interface

Create a class that implements the interface Runnable and override run() method:

class MyThread implements Runnable { ..... public void run() { // thread body of execution } } Creating Object: MyThread myObject = new MyThread(); Creating Thread Object: Thread thr1 = new Thread( myObject ); Start Execution: thr1.start();

84

An example
class MyThread implements Runnable { public void run() { System.out.println(" this thread is running ... "); } }
class ThreadEx2 { public static void main(String [] args ) { Thread t = new Thread(new MyThread()); t.start(); } }

85

Life Cycle of Thread


new
start() I/O completed

ready
notify()

resume() Time expired/ interrupted

waiting
dispatch

sleeping
sleep()

blocked

wait()

suspend()

running
completion
86

Block on I/O

stop()

dead

Introduction to Java 2 Programming


Lecture 5 Array and Collections

Overview

Arrays
Working with arrays Java API support for arrays

Collection classes
Types of collection Working with Collections

Java Arrays The Basics

Declaring an array

int[] myArray; int[] myArray = new int[5]; String[] stringArray = new String[10]; String[] strings = new String[] {one, two};

Checking an arrays length


Looping over an array

int arrayLength = myArray.length;

for(int I=0; I<myArray.length; i++) { String s = myArray[i]; }

Java Arrays Bounds Checking

Bounds checking
Java does this automatically. Impossible to go beyond the end of an array (unlike C/C++) Automatically generates an ArrayIndexOutOfBoundsException

Java Arrays Copying


Dont copy arrays by hand by looping over the array The System class has an arrayCopy method to do this efficiently

int array1[] = new int[10]; int array2[] = new int[10]; //assume we add items to array1 //copy array1 into array2 System.arrayCopy(array1, 0, array2, 0, 10); //copy last 5 elements in array1 into first 5 of array2 System.arrayCopy(array1, 5, array2, 0, 5);

Java Arrays Sorting


Again no need to do this by hand. The java.util.Arrays class has methods to sort different kinds of arrays

int myArray[] = new int[] {5, 4, 3, 2, 1}; java.util.Arrays.sort(myArray); //myArray now holds 1, 2, 3, 4, 5

Sorting arrays of objects is involves some extra work, as well see later

Java Arrays

Advantages
Very efficient, quick to access and add to Type-safe, can only add items that match the declared type of the array

Disadvantages
Fixed size, some overhead in copying/resizing Cant tell how many items in the array, just how large it was declared to be Limited functionality, need more general functionality

Java Collections

What are they?


A number of pre-packaged implementations of common container classes, such as LinkedLists, Sets, etc. Part of the java.util package.

Advantages
Very flexible, can hold any kind of object

Disadvantages
Not as efficient as arrays (for some uses) Not type-safe. Store references to Object

Java Collections

Two Types of Containers Collections


Group of objects, which may restricted or manipulated in some way E.g. an ordered to make a List or LinkedList E.g. a Set, an unordered group which can only contain one of each item

Maps
Associative array, Dictionary, Lookup Table, Hash A group of name-value pairs

Java Collections

Java Collections

Several implementations associated with each of the basic interfaces Each has its own advantages/disadvantages Maps
HashMap, SortedMap

Lists
ArrayList, LinkedList

Sets
HashSet, SortedSet

Java Collections The Basics

HashMap and ArrayList are most commonly encountered Usual object creation syntax Generally hold references to the interface and not the specific collection
Can then process them generically
List myList = new ArrayList(); List otherList = new ArrayList(5); Map database = new HashMap(); Set things = new HashSet();

Java Collections Adding Items

For Collections, use add()

List myList = new ArrayList(); myList.add(A String); myList.add(Other String);

For Maps, use put()

Map myMap = new HashMap(); myMap.put(google, http://www.google.com); mpMap.put(yahoo, http://www.yahoo.com);

Java Collections Copying

Very easy, just use addAll()

List myList = new ArrayList(); //assume we add items to the list List otherList = new ArrayList(); myList.addAll(myList);

Collections Getting Individual Items

Use get()
Note that we have to cast the object to its original type.

Collections

String s = (String)myList.get(1); //get first element String s2 = (String)myList.get(10); //get tenth element

Maps

String s = (String)myMap.get(google); String s2 = (String)mpMap.get(yahoo);

Collections Getting all items

For Lists, we could use a for loop, and loop through the list to get() each item

But this doesnt work for Maps. To allow generic handling of collections, Java defines an object called an Iterator
An object whose function is to walk through a Collection of objects and provide access to each object in sequence

Collections Getting all items


Get an iterator using the iterator() method Iterator objects have three methods:

next() gets the next item in the collection hasNext() tests whether it has reached the end remove() removes the item just returned

Basic iterators only go forwards


Lists objects have a ListIterator that can go forward and backward

Collections Getting all items

Simple example:

List myList = new ArrayList(); //we add items Iterator iterator = myList.iterator(); while (iterator.hasNext()) { String s = (String)iterator.next(); //do something with it }

Collections Other Functions

The java.util.Collections class has many useful methods for working with collections
min, max, sort, reverse, search, shuffle

Virtually all require your objects to implement an extra interface, called Comparable

Collections Comparable

The Comparable interface labels objects that can be compared to one another.
Allows sorting algorithms to be written to work on any kind of object so long as they support this interface

Single method to implement Returns


A negative number of parameter is less than the object Zero if theyre equal A positive number if the parameter is greater than the object

public int compareTo(Object o);

Collections Comparator

Like Comparable, but is a stand-alone object used for comparing other objects
Useful when you want to use your criteria, not that of the implementor of the object. Or altering the behaviour of a system

Many of the methods in the Collections object all a Comparator to be specified Again has single method:
public int compare(Object obj1, Object obj2)

Collections Comparator Example

Java String comparison is lexicographic not alphabetic, I.e. based on the character set, not alphabetic order

public class AlphaComparison implements Comparator { public int compare(Object obj1, Object obj2) { String s1 = ((String)o1).toLowerCase(); String s2 = ((String)o2).toLowerCase(); return s1.compareTo(s2); } }

Collections

Sorting and Searching are used often With Generics, the code only needs written once
Can then be used in any situation Provided were dealing with Comparable objects

Java has predefined these methods for us


Arrays.sort() Arrays.binarySearch() Operate on arrays

There are other ways of storing a group of related objects


Offer performance benefits over arrays in some situations Offer a conceptual implementation of some container
e.g. a Set
Doesnt contain duplicates Can Add or Remove objects Can perform Union, Intersection, Difference operations An object is either in the Set or it isnt

Collections

Java refers to these as Collections


Containers of other data objects Collect related objects into a single object

Provides conceptual view of the container


Consider a File System for example
Directory Tree of Files Independent of Storage media (Hard Disk, CD, Flash Drive) Collections are similar

Separate Interface with which we access the stored objects from the Implementation

Used often enough that Java provides standard implementation of each type of Collection
Collection
List (Vector) Set
SortedSet

Queue

Map (Hashtable)
SortedMap

Stack

See Java API

List

What is a List?
Lets consider lists we make in every day life What kinds are there? What information does each store? How can we access and change each?

A List is a sequence of items or objects


A container of them Implied arbitrary order of the elements Size shrinks and grows with the number of items in the list We can access an element if we know its position in the List We can insert an item to any position We can remove an item from any position

List Implementation

We now have a concept of a List


A scheme by which we store and access elements in the List This is defined by the List Interface in Java
See Java API Notice add(), get(), remove(), contains() Assumes objects have well defined equals() method

This defines the behavior of a List


In order to use a list, though, we need implement it

There are two common concrete implementations


ArrayList
Uses a private array to store and order the elements

LinkedList
Uses a chain of nodes, each of which stores a single item

When to use each requires knowledge of the implementation

ArrayList

We use an array to store the items in the List


Arrays have a fixed size List has an arbitrary size If our list has n elements, we need an array of size n or MORE
We can leave extra empty spaces to store elements added later We can resize the array if we need more space

List needs to maintain an order to the elements


Array does this for us

But consider
Inserting or adding an element
Need free the index where the element is to be stored Need to keep maintain the same order with the new element added Requires shifting some elements to higher indices

Removing an element
Array now has an unused index Have to shift elements to lower indices to keep ordering

A lot of shifting!!!

NOTE: The Vector class provides the same implementation, but provides synchronization for multithreaded applications (slower)

LinkedList

The strict array indexing causes this need for shifting


Can we avoid this?

Consider this class


public class Node { private Object value; private Node next; }

Each Node contains a reference to another Node


Forms a chain of Nodes

If we keep a reference to the first Node, we can access any of them by repeatedly accessing the next reference
Show on board Getting element at position I requires us to traverse the chain
Disadvantage over an array

Consider adding, and removing elements again

Which and How to Use

ArrayList when
Add and remove mostly from end of list Perform a lot of additions

LinkedList when
Frequent additions and removals at arbitrary positions, especially beginning

This is discussed further in CS 0445 We want to hide the implementation of a collection as much as possible
We only care that we have List List Interface provides this abstraction See ex27.java

Set

Similar to a List except


No order to the elements Cannot contain duplicate objects

A Set is a collection of objects that cannot contain duplicates


No two objects o1 and o2 in a Set can exist such that o1.equals(o2) is true Care must be taken when storing mutable objects
Cannot change data in an object that makes o1.equals(o2) true after theyve been added to the Set

Operations on a Set
Add an element add() Remove an element remove() Test for inclusion contains() Union (combine elements from two Sets) addAll() Intersection (keep elements two Sets have in common) retainAll() Difference (keep elements not found in a second Set) removeAll()

Implementations
HashSet stores elements in a Hashtable LinkedHashSet: similar to HashSet TreeSet stores elements in a Binary Tree

HashSet

Imagine implementing a Set with an array


To maintain the constraint that the Set doesnt contain duplicates, wed have to do something like: for(int i = 0; i < count; i++) if(array[i].equals(newElement)) return; //dont add new element array[count++] = newElement; We have to check each item before knowing if a duplicate existed in the array

What if we could know the index where a duplicate would be stored if it was in the Set?
Just check the element(s) at that index with equals() Add the new Element if not there

This is how a Hashtable works


Uses newElement.hashCode() to find index

Notice the need for the contract of equals() and hashCode()


Why?

Iterators

Weve seen two types of Collections so far


List Set

Recall how often weve used the following code with arrays
for(int i = 0; i < array.length; i++) {} Loop for each element of the array Use variable i to keep track of position in the array

This is a common and needed operation for any Collection


How do we do this when a Collection has no implied order? How do we do this in a common way for any type of Collection?

An Iterator is a object that can traverse over and provide access to each element
User doesnt know how it finds the next element

Using Iterators

Iterator class defines two methods


hasNext()
returns true if there is another element to examine

next()
returns the current element as an Object Prepares the iterator to return the next element

Loop then looks like:


for(Iterator i=collect.iterator(); i.hasNext();) { MyClass item = (MyClass) i.next(); //Process the item }

Java provides a shorthand version of this, called foreach loop:


for(Object o : collect) { MyClass item = (MyClass) o; // Process the item } No need to explicitly declare an Iterator collect variable must be an instance of a class that implements Iterable interface

See ex28.java

Order in Sets

The HashSet Class is the simplest implementation of the Set interface


Iterator can return the elements in any particular order Can be chaotic

It can be advantageous to ensure an Iterator returns the elements is some consistent order Two implementations of the Set Interface do this
LinkedHashSet
Like HashSet Iterator returns elements in the order in which they were added to the Set

TreeSet
Iterator returns elements in sorted order Requires stored objects to be Comparable Elements actually stored in sorted order in a binary tree

See ex28b.java

Queue

We often dont need to be able to modify all a Collections elements


Can even be advantageous to prevent access to every element Force modification of the Collection according to specific rules

A queue is an ordered collection of objects that:


Allows new items to be added only to the end Allows items to be removed only from the front Similar to a waiting line First item added to the end is the first item removed from the front (FIFO ordering First In, First Out) No other item can be removed until the first item is removed

Implementation
How could we implement a Queue? An array could impose the needed ordering
Would require a lot of shifting Circular array is still cumbersome

LinkedList class also implements the Queue interface


Ideal for a Queue Why?

See ex28c.java

Stack

Consider a stack of plates on a spring in a bin in a cafeteria


When a plate is added, spring compresses, hiding all plates below Only plate that can be removed is the top plate
The last one that was added

This is the behavior of a Stack

A Stack is a data structure where objects can only be added to or removed from the top
Last item added is the first to be removed LIFO ordering Last In, First Out

Stack Implementation

How would this best be implemented?


Array Linked list

Either would be efficient Array doesnt require the extra storage of saving a reference to each object java.util.Stack is a concrete class
Can create instances of it Ex: Collection collection = new Stack(); Stack stack = new Stack();

See ex28d.java

Map

The Map Interface differs from a Collection Defines a mapping from one set of objects to another
Like a function in Mathematics: y = f(x) Given an object, x, the map returns an object, y Refer to x as the key

An array fits this description


Maps an int to an object stored in the array Each int uniquely identifies and is associated with one of the objects

A Map allows us to impose a logical relationship between an object and its index (key)
Ex:
The title a CD could be the index of our AbstractCD class A Persons name could index their phone number (Phone Book)

Map Implementation

Recall our discussion of a Set


Used hashCode() to store object in array Used compareTo() to order object in tree

We now have two objects


One is the key for other Use hashCode() of key to find location to store the other object Use compareTo() of key to order second object in a binary tree Indexing object then needs to have well defined equals(), hashCode(), and compareTo() Stored object doesnt have to be as strictly implemented

Analogous Map Implementations to Set


HashMap LinkedHashMap TreeMap
Implements SortedMap Interface

See ex29.java

Iterating over a Map

A Map is a complex data structure


Keys Values

The keySet() method returns a Set containing all the keys stored in the Map
Map cannot contain duplicate keys Iterate over this Set

The values() method returns a Collection of all objects that have an associated key
May contain duplicate objects Iterate over this collection

The entrySet() method returns a Set of all the (key, value) pairs
Each object in the Set is of the type Map.Entry Iterate over this Set

You might also like