Monday, November 23, 2009

All about Java Inner class with sample.

package blog.java;

class OuterClass {

private String aVariable = "Normal private variable.";

private static String staticVar = "private static variable.";

// Normal Inner class example.
class InnerClass {
public void aMethod() {
System.out.println("aMethod of InnerClass called.");
// Any Variable of the outer class is accessable from inner class.
System.out.println(" Accessing aVariable: " + aVariable);
System.out.println();

}
}

// Static Inner class example.
static class staticInnerClass {

void aMethod() {
System.out.println("aMethod of staticInnerClass called.");
// Only Static Variable of the outer class is accessable from inner
// class.
System.out.println(" Accessing a static Variable:" + staticVar);
System.out.println();
}
}

// Method-Local Inner Class example.
public void aMethod() {
final String msg = "Method-Local Inner Classes";
System.out.println("aMethod from the OuterClass called.");

// Method-Local Inner Class
class MethodLocalInnerClass {

String variable = "MethodLocalInnerClass variable.";

void aMethod() {
System.out
.println("aMethod from the MethodLocalInnerClass called.");
// Can access final local variable declared in the method.
System.out
.println(" Accessing a local Variable in the method: "
+ msg);
System.out.println();
}

}

// initialization of Method-Local Inner Class
MethodLocalInnerClass methodLocalInnerClass = new MethodLocalInnerClass();
System.out.println("variable from the MethodLocalInnerClass: "
+ methodLocalInnerClass.variable);
methodLocalInnerClass.aMethod();

}

public void initInnerClass() {
// Normal invocation of InnerClass works within the outer class
InnerClass innerClass = new InnerClass();
innerClass.aMethod();
}
}

class DemoClass {
public void aMethod() {
System.out.println("aMethod called from demoClass");
}

}

interface DemoInterface {
void aMethod();
}

class MethodArgInnerClass {
public void anotherMethod(DemoInterface demoInterface) {
System.out.println("anotherMethod of methodArgInnerClass called.");
demoInterface.aMethod();
}
}

public class InnerClassSample {

public static void main(String[] args) {
// Get a reference to outer class.
OuterClass outerClass = new OuterClass();

// initialization of Normal Inner class
OuterClass.InnerClass innerClass = outerClass.new InnerClass();
innerClass.aMethod();

// initialization of Static Inner class
OuterClass.staticInnerClass innerClass2 = new OuterClass.staticInnerClass();
innerClass2.aMethod();

// Demo of Method-Local Inner Class
outerClass.aMethod();

// Following are the demo of Anonymous Inner class in action.
/**
* Example of overriding the method: This anonymous class now
* becomes the subclass of the DemoClass.java
*/
DemoClass demoClass = new DemoClass() {

public void aMethod() {
System.out.println("aMethod over ridden from "
+ "Anonymous Inner class of demoClass");
}
};

demoClass.aMethod();

// Example of implementing a Interface
DemoInterface interface1 = new DemoInterface() {

public void aMethod() {
System.out.println("aMethod method of the DemoInterface "
+ "implemented by Anonymous Inner class");

}

};

interface1.aMethod();

// Example of Anonymous Inner class in method argument.
MethodArgInnerClass innerClass3 = new MethodArgInnerClass();
innerClass3.anotherMethod(new DemoInterface() {

public void aMethod() {
System.out.println("Example of Anonymous Inner class"
+ " in method argument");
}
});

}

}

Implementing Queue using Stack


This is one of the common question asked in interview. How do you implement a queue using stack.
Queue has operations enqueue and dequeue. While stack has operations like push and pop.

Solution1: 
We need 2 stack for this solution.

Enqueue operation in queue
if (stack1 is empty)
True:
push the element into the stack1
False:
pop the elements from stack1 and push them to stack2
push the incoming element to stack1
pop the elements from stack2 and push them again to stack1

For dequeue operation
Pop the element from the stack1

But this solution is not efficient. This can be altered to make it more efficient.
Solution 2:
The two stack now named as inbox and outbox.

Enqueue operation in queue
Push the incoming item to the inbox.

For dequeue operation
if(outbox is empty)
pop the elements from inbox and push them to outbox
pop the element from outbox.

By this, each element is popped and pushed only twice.

Here is the implementation of the same in java for reference.



package blog.java;


import java.util.Stack;



class Queue {
private Stack inbox = new Stack();
private Stack outbox = new Stack();


public void queue(Integer integer) {
inbox.push(integer);
}


public void dequeue() {
if (outbox.isEmpty()) {
while (!inbox.isEmpty())
outbox.push(inbox.pop());
}
System.out.println(outbox.pop());
}
}



public class QueueWithTwoStack {


/**
* @param args
*/
public static void main(String[] args) {
Queue queueTest = new Queue();
queueTest.queue(1);
queueTest.queue(2);
queueTest.queue(3);
queueTest.queue(4);
queueTest.dequeue();
queueTest.dequeue();
queueTest.queue(5);
queueTest.queue(6);
queueTest.queue(7);
queueTest.queue(8);
queueTest.dequeue();
queueTest.dequeue();
queueTest.dequeue();
queueTest.dequeue();
queueTest.dequeue();
queueTest.dequeue();


}


}