Thursday, May 29, 2008

Miscellaneous Java Code


Fetching Line Number in Java Code

1.
new Throwable()).getStackTrace()[0].getLineNumber()

2.

StackTraceElement[] st = Thread.currentThread().getStackTrace();
int lineNumber = st [st.length-1].getLineNumber();

Getting a stack trace can be slow. Using this to do logging can adversely effect the performance of an application.

Friday, May 16, 2008

Observer Pattern

The Observer pattern allows the subject and observer to form a publish-subscribe relationship. Through the Observer pattern, observers can register to receive events from the subject. When the subject needs to inform its observers of an event, it simply sends the event to each observer.

The benefit: it decouples the observer from the subject. The subject doesn't need to know anything special about its observers. Instead, the subject simply allows observers to subscribe. When the subject generates an event, it simply passes it to each of its observers.

Consider the following Java example

public interface Subject {
public void addObserver( Observer o );
public void removeObserver( Observer o );
}

In the code above, the Subject interface defines the methods that a Subject must implement in order for Observers to add and remove themselves from the Subject.

public interface Observer {
public void update( Subject o );
}

The Observer interface (above) lists the methods that an Observer must implement so that a Subject can send an update notification to the Observer.

Let's consider a simple implementation of Subject -- an IntegerDataBag:

import java.util.ArrayList;
import java.util.Iterator;
public class IntegerDataBag implements Subject {
private ArrayList list = new ArrayList();
private ArrayList observers = new ArrayList();
public void add( Integer i ) {
list.add( i );
notifyObservers();
}
public Iterator iterator() {
return list.iterator();
}
public Integer remove( int index ) {
if( index < i =" (Integer)" i =" observers.iterator();" o =" (">

IntegerDataBag holds onto Integer instances. The IntegerDataBag also allows Observers to add and remove themselves.

Consider these two implementations of Observer -- IntegerAdder and IntegerPrinter:

import java.util.Iterator;
public class IntegerAdder implements Observer {
private IntegerDataBag bag;
public IntegerAdder( IntegerDataBag bag ) {
this.bag = bag;
bag.addObserver( this );
}
public void update( Subject o ) {
if( o == bag ) {
System.out.println( "The contents of the IntegerDataBag have changed." );
int counter = 0;
Iterator i = bag.iterator();
while( i.hasNext() ) {
Integer integer = ( Integer ) i.next();
counter+=integer.intValue();
}
System.out.println( "The new sum of the integers is: " + counter );
}
}
}

import java.util.Iterator;
public class IntegerPrinter implements Observer {
private IntegerDataBag bag;
public IntegerPrinter( IntegerDataBag bag ) {
this.bag = bag;
bag.addObserver( this );
}
public void update( Subject o ) {
if( o == bag ) {
System.out.println( "The contents of the IntegerDataBag have changed." );
System.out.println( "The new contents of the IntegerDataBag contains:" );
Iterator i = bag.iterator();
while( i.hasNext() ) {
System.out.println( i.next() );
}
}
}
}

IntegerAdder and IntegerPrinter add themselves to the integer bag as observers. When an IntegerAdder receives an update, it sums up the Integer values held in the bag and displays them. Likewise, when IntegerPrinter receives an update, it prints out the Integers held in the bag.

Here is a simple main() that exercises these classes:

public class Driver {
public static void main( String [] args ) {
Integer i1 = new Integer( 1 ); Integer i2 = new Integer( 2 );
Integer i3 = new Integer( 3 ); Integer i4 = new Integer( 4 );
Integer i5 = new Integer( 5 ); Integer i6 = new Integer( 6 );
Integer i7 = new Integer( 7 ); Integer i8 = new Integer( 8 );
Integer i9 = new Integer( 9 );
IntegerDataBag bag = new IntegerDataBag();
bag.add( i1 ); bag.add( i2 ); bag.add( i3 ); bag.add( i4 );
bag.add( i5 ); bag.add( i6 ); bag.add( i7 ); bag.add( i8 );
IntegerAdder adder = new IntegerAdder( bag );
IntegerPrinter printer = new IntegerPrinter( bag );
// adder and printer add themselves to the bag
System.out.println( "About to add another integer to the bag:" );
bag.add( i9 );
System.out.println("");
System.out.println("About to remove an integer from the bag:");
bag.remove( 0 );
}
}



Friday, May 9, 2008

J2SE 5.0 Language Features

J2SE5.0 has the following noteworthy language features.

Enhanced For Loop

The new enhanced for loop provides a simple, consistent syntax for iterating over collections and arrays.

Consider the following example. A collection companies contains the following names: Sun, BEA Weblogic, Oracle.

Accessing the collection without enhanced loop.

for(Iterator it = companies.iterator();it.hasNext();){//Line1
String cmp = (String)it.next();//Line2
System.out.println(cmp);
}


We need to declare Iterator(Line1), type cast the value(Line2) to access the value.

This is prone to error for the following reasons.
1. Use of Iterator
2. TypeCasting, since the Type of data in Collection companies might not be known until run-time.

Accessing the collection with enhanced loop.

for(String it:companies){
System.out.println(it);
}


The use of : reads as for each string it in companies. This approach is cleaner and robust. It does not make use of Iterator and TypeCasting is not required(The compiler takes care of these thing in background).

Enhanced loop Limitations

It cannot be used to traverse collection in which we need to add or remove entries.

for(Iterator it = companies.iterator();it.hasNext();){
if(it.next().equals("Oracle")){
it.remove();
}
}


From the above code we can see that in order to remove Oracle from the collection, we need to iterate the collection.

Sample Code For Enhance for Loop

public void EnhancedForLoop() {
List companies = new ArrayList();

companies.add("Sun");
companies.add("BEA Weblogic");
companies.add("Oracle");

// Without Enhanced
for (Iterator it = companies.iterator(); it.hasNext();) {
String cmp = (String) it.next();
System.out.println(cmp);
}

// With Enhanced
for (String it : companies) {
System.out.println(it);
}

// Without Enhanced
for (Iterator it = companies.iterator(); it.hasNext();) {
if (it.next().equals("Oracle")) {
it.remove();
}
}
System.out.println(companies);
}


Annotations

Generics