Code man! Right now!

It feels so good when girls go gaga when you say your a Masters student. And then more drooling when you say you are from the computer engineering department. No, I am not making up this stuff. Apparently they think about us making the next big Facebook. Aaah. That explains doesn’t it? They ask me “So you’ll get rich pretty soon right?” I don’t have the heart to say otherwise. Basically, I do love all the attention. 😛

Anyways, I was wondering. Why not make it big? I can’t own a Ferrari if I end up working in some company. Its true. But not everyone ends up with a successful start up either. But ya, who cares? I mean, people, we should just go for it. I loved this video. Inspires to learn coding. I’m putting it up on my wall. Because guys, programming is important.

Code man! Right now!

Design Pattern: Strategy

 Strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. It lets the algorithm vary independently from clients that use it.

Strategy Design Pattern
Strategy Design Pattern

Abstract Class: Duck.java

We create objects  after sub classing it into a concrete class from an abstract type. In our case, is the Duck Class. This provides the basis for all the XxxDuck objects that are created. Two things to be mentioned;

  1. We are programming the different “behavior” to an interface. And this could be an abstract class as well. References to these instance variables are provided as instance variables in the Class Definition.
  2. Public “Setters” are provided so that the behavior of the object can be set or changed dynamically as shown in this example.
package com.npk.strategy;

public abstract class Duck {

FlyBehavior flyBehavior;
QuackBehavior quackBehavior;

public abstract void display();

public void setFlyBehavior(FlyBehavior flyBehavior){
this.flyBehavior = flyBehavior;
}

public void setQuackBehavior(QuackBehavior quackBehavior){
this.quackBehavior = quackBehavior;
}

public void performFly(){
flyBehavior.fly();
}

public void performQuack(){
quackBehavior.quack();
}

public void performSwim(){
System.out.println("All ducks can swim!");
}
}

Interface: FlyBehavior.java and QuackBehavior.java

Any variable behavior of an object are to be programmed to an interface.
This way, you get two things:

  1. Compostion
  2. Loosely coupled objects.

Both of which are good OO Designs aspects.


package com.npk.strategy;

public interface FlyBehavior {

public void fly();
}

package com.npk.strategy;

public interface QuackBehavior {

public void quack();
}

Concrete Implementation: DummyDuck.java

We subclass the abstract Duck class to get a concrete DummyDuck class where we can set the behavior in the class constructor ( optional )


package com.npk.strategy;

public class DummyDuck extends Duck {

public DummyDuck(){
this.setFlyBehavior(new FlyNoWay());
this.setQuackBehavior(new SquekQuack());
}

@Override
public void display() {
System.out.println("This is a dummy duck.");

}

}

Concrete classes: FlyNoWay.java and SquekQuack.java

These form the actual implementation of the FlyBehavior and the QuackBehavior interfaces respectively.


package com.npk.strategy;

public class FlyNoWay implements FlyBehavior {

@Override
public void fly() {
System.out.println("Cannot fly.");

}

}

package com.npk.strategy;

public class SquekQuack implements QuackBehavior {

@Override
public void quack() {
System.out.println("Duck squeking.");

}

}

The Application Launcher We show two things here.

  1. Setting the behavior using the constructor.
  2. Changing the set behavior using the setters provided.

package com.npk.strategy;

public class Launcher {

public static void main(String[] args) {
Duck duck = new DummyDuck();
duck.display();
duck.performFly();
duck.performQuack();

System.out.println("---------------------");
duck.setFlyBehavior(new FlyWithWings());
duck.setQuackBehavior(new MuteQuack());

duck.performFly();
duck.performQuack();
}

}

The final output


This is a dummy duck.
Cannot fly.
Duck squeking.
---------------------
Duck flying.
Mute quack.

Design Pattern: Strategy

Linked Lists in Java

You might want to check out these before continuing:

https://linuxjunkies.wordpress.com/2010/11/18/data-structures-using-java-part-6-linked-lists-part-1/

https://linuxjunkies.wordpress.com/2010/11/26/data-structures-using-java-part-7-linked-lists-part-2-doubly-linked/

Linked List

ListNode Class


public class ListNode {

	Object data;
	ListNode nextNode;
	
	ListNode (Object object, ListNode node){
		data = object;
		nextNode = node;
	}
	
	ListNode (Object object){
		this(object,null);
	}
	
	Object getObject(){
		return data;
	}
	
	ListNode getNext(){
		return nextNode;
	}
}

List Class


public class List {

	private ListNode firstNode;
	private ListNode lastNode;
	private String name;
	
	public List(){
		this("list");
	}
	
	public List(String listname){
		name = listname;
		firstNode = lastNode = null;
	}
	
	public void insertAtFront(Object item){
		if (isEmpty())
			firstNode = lastNode = new ListNode(item);
		else
			firstNode = new ListNode(item, firstNode);
	}
	
	public void insertAtBack(Object item){
		if (isEmpty())
			firstNode = lastNode = new ListNode(item);
		else
			lastNode = lastNode.nextNode = new ListNode(item);
	}
	
	public Object removeFromFront() throws EmptyListException{
		if (isEmpty())
			throw new EmptyListException(name);
		Object removed = firstNode.data;
		
		if( firstNode == lastNode)
			firstNode = lastNode = null;
		else
			firstNode = firstNode.nextNode;
		
		return removed;
	}
	
	public Object removeFromBack() throws EmptyListException{
		if (isEmpty())
			throw new EmptyListException(name);
		
		Object removed = lastNode.data;
		
		if( firstNode == lastNode)
			firstNode = lastNode = null;
		else{
			
			ListNode current = firstNode;
			
			while(current.nextNode != lastNode)
				current = current.nextNode;
			
			lastNode = current;
			current.nextNode = null;	
		}
		return removed;
		
	}
	
	public boolean isEmpty(){
		return firstNode == null;
	}
	
	public void print(){
		if (isEmpty()){
			System.out.println("List is empty");
			return;
		}
		
		ListNode current = firstNode;
		while (current != null){
			System.out.printf("%s --> ", current.data);
			current = current.nextNode;
		}
		System.out.println();
	}
	
	public int length(){
		int length = 0;
		
		if (isEmpty()){
			return 0;
		}
		
		ListNode current = firstNode;
		while (current != null){
			current = current.nextNode;
			length++;
		}
		return length;
	}
	
	public int recursiveSize(){
		return recursiveLength(firstNode);
	}
	
	public int recursiveLength(ListNode current){
		
		if (isEmpty()){
			return 0;
		}
		
		if (current == null)
			return 0;
		
		return (1 + recursiveLength(current.nextNode));
	}
	
}
	

ListTest Class


public class ListTest {

	public static void main(String[] args){
		
		List list = new List();
		
		list.insertAtFront( "four" ); 
		list.print();             
		list.insertAtFront( "two" ); 
		list.print();            
		list.insertAtBack( "six" );  
		list.print();          
		list.insertAtBack( "nine" );  
		list.print();            
		
		System.out.printf("Length: %d%n", list.recursiveSize());
		System.out.printf("Length: %d%n", list.length());
		
		try{
		    System.out.printf( "%s removed\n", list.removeFromFront());
		    list.print();
		    System.out.printf( "%s removed\n", list.removeFromFront());
		    list.print();
		    System.out.printf( "%s removed\n", list.removeFromBack());
		    list.print();
		    System.out.printf( "%s removed\n", list.removeFromBack());
		    list.print();
		}catch ( EmptyListException e ){
			e.printStackTrace();
		}
		
		System.out.printf("Length: %d%n", list.recursiveSize());
		System.out.printf("Length: %d%n", list.length());
		
		       
	}
}

This is what you get

four --> 
two --> four --> 
two --> four --> six --> 
two --> four --> six --> nine --> 
Length: 4
Length: 4
two removed
four --> six --> nine --> 
four removed
six --> nine --> 
nine removed
six --> 
six removed
List is empty
Length: 0
Length: 0
Linked Lists in Java

String Reversal in Java using StringBuffer, toCharacterArray and Recursion

Using StringBuffer Class

new StringBuffer(name).reverse().toString()

Using CharArray and StringBuilder

        public static String charReverse(String data){
		StringBuilder sb = new StringBuilder();
		char[] ca = data.toCharArray();
		
		for (int i=data.length()-1; i>=0;i--){
			sb.append(ca[i]);
		}
		return sb.toString();
	}

Using Recursion

public static String recursiveReverse(String data){
		
		if (data.length() < 2)
			return data;
		
		return recursiveReverse(data.substring(1)) + data.charAt(0);
	}

StringReversal Class

public class StringReversal {

	public static void main (String[] args){
		String name = "linuxjunkies";
		
		System.out.println("StringBuffer: " + new StringBuffer(name).reverse().toString());
		System.out.println("CharacterArray: " + charReverse(name));
		System.out.println("Recursion: " + recursiveReverse(name));
	}
	
	public static String charReverse(String data){
		StringBuilder sb = new StringBuilder();
		char[] ca = data.toCharArray();
		
		for (int i=data.length()-1; i>=0;i--){
			sb.append(ca[i]);
		}
		return sb.toString();
	}
	
	public static String recursiveReverse(String data){
		
		if (data.length() < 2)
			return data;
		
		return recursiveReverse(data.substring(1)) + data.charAt(0);
	}
}

The Output

StringBuffer: seiknujxunil
CharacterArray: seiknujxunil
Recursion: seiknujxunil
String Reversal in Java using StringBuffer, toCharacterArray and Recursion

Binary Tree and Tree Traversals using Java

    The root node of a tree is the node with no parents. There is at most one root node in a rooted tree.A leaf node has no children.
    The depth of a node n is the length of the path from the root to the node. The set of all nodes at a given depth is sometimes called a level of the tree. The root node is at depth zero.
    The height of a tree is the length of the path from the root to the deepest node in the tree. A (rooted) tree with only one node (the root) has a height of zero.
    Siblings are nodes that share the same parent node.
    A node p is an ancestor of a node q if it exists on the path from q to the root. The node q is then termed a descendant of p.
    The size of a node is the number of descendants it has including itself.
    In-degree of a node is the number of edges arriving at that node.
    Out-degree of a node is the number of edges leaving that node.
    The root is the only node in the tree with In-degree = 0.

BInary Tree

TreeNode Class


public class TreeNode{

	TreeNode leftNode;
	TreeNode rightNode;
	int data;
	
	public TreeNode(int value){
		data = value;
		leftNode = rightNode = null;
	}
	
	public void insert(int value){
		if (value < data){
			if (leftNode == null)
				leftNode = new TreeNode(value);
			else
				leftNode.insert(value);
		}
		else if (value > data){
			if (rightNode == null)
				rightNode = new TreeNode(value);
			else
				rightNode.insert(value);
		}
	}

}

Preorder Traversal

  preorder(node)
  if node = null then return
  print node.value
  preorder(node.left) 
  preorder(node.right)

Preorder Traversal

Postorder Traversal

  postorder(node)
  if node = null then return
  postorder(node.left)
  postorder(node.right)
  print node.value

PostOrder Traversal

Inorder Traversal

  inorder(node)
  if node = null then return
  inorder(node.left)
  print node.value
  inorder(node.right)

Inorder Traversal

Queue based Level order Traversal

levelorder(root) 
  q = empty queue
  q.enqueue(root)
  while not q.empty do
    node := q.dequeue()
    visit(node)
    if node.left ≠ null
      q.enqueue(node.left)
    if node.right ≠ null
      q.enqueue(node.right)

Level Order

Tree Class


public class Tree {

	private TreeNode root;
	
	Queue queue = new Queue();
	
	public Tree(){
		root = null;
	}
	
	public void insertNode(int value){
		
		if ( root == null)
			root = new TreeNode(value);
		else
			root.insert(value);
	}
	
	public void preorderTraversal(){
		preorder(root);
	}
	
	public void inorderTraversal(){
		inorder(root);
	}
	
	public void postorderTraversal(){
		postorder(root);
	}
	
	public void levelorderTraversal(){
		levelorder(root);
	}
	
	public void levelorder(TreeNode node){
		if (node == null)
			return;

		if (node == root)
			queue.offer(node);
		
		if (node.leftNode != null)
			queue.offer(node.leftNode);
		if (node.rightNode != null)
			queue.offer(node.rightNode);
		
		System.out.printf("%d ", queue.poll().data);
		
		levelorder(queue.peek());
	}
	
	public void preorder(TreeNode node){
		
		if (node == null)
			return;
		
		System.out.printf("%d ", node.data);
		preorder(node.leftNode);
		preorder(node.rightNode);
		
	}

	public void postorder(TreeNode node){
		
		if (node == null)
			return;
		
		postorder(node.leftNode);
		postorder(node.rightNode);
		System.out.printf("%d ", node.data);
	}

	public void inorder(TreeNode node){
		
		if (node == null)
			return;
		
		inorder(node.leftNode);
		System.out.printf("%d ", node.data);
		inorder(node.rightNode);
	}

}

TreeTest Class

import java.util.Random;


public class TreeTest {

	public static void main(String[] args){
		Tree tree = new Tree();
		int value;
		Random random = new Random();
		
		System.out.println("Inserting values");
		for (int i=1; i<=10;i++){
			value=random.nextInt(100);
			System.out.printf("%d ", value);
			tree.insertNode(value);
		}
		System.out.println();
		System.out.println("Preorder");
		tree.preorderTraversal();
		System.out.println();
		System.out.println("Postorder");
		tree.postorderTraversal();
		System.out.println();
		System.out.println("Inorder");
		tree.inorderTraversal();
		System.out.println();
		System.out.println("Levelorder");
		tree.levelorderTraversal();
	}
}

Of course, you need the Queue DS for level order traversal.


import java.util.ArrayList;
import java.util.List;


public class Queue {

	private List qlist;
	
	public Queue(){
		qlist = new ArrayList();
	}
	
	public void offer(TreeNode o){
		if (qlist.isEmpty())
			qlist.add(0, o);
		else
			qlist.add(qlist.size(), o);
	}
	
	public TreeNode poll(){
		if (qlist.isEmpty())
			return null;
		else
			return qlist.remove(0);
	}
	
	public TreeNode peek(){
		if (qlist.isEmpty())
			return null;
		else
		return qlist.get(0);
	}
}

And finally the output

Inserting values
87 77 81 89 4 26 23 27 57 1 
Preorder
87 77 4 1 26 23 27 57 81 89 
Postorder
1 23 57 27 26 4 81 77 89 87 
Inorder
1 4 23 26 27 57 77 81 87 89 
Levelorder
87 77 89 4 81 1 26 23 27 57 
Binary Tree and Tree Traversals using Java

The entire Server code in all its Glory!


import java.io.*;
import java.net.*;
import java.util.*;

public class Server {

 ArrayList clientOutputStreams;

 //String[] output;

 public class ClientHandler implements Runnable{

 BufferedReader reader;
 Socket sock;

 //constructor
 public ClientHandler(Socket clientSocket){

 try{
 sock = clientSocket;
 InputStreamReader isReader = new InputStreamReader(sock.getInputStream());
 reader = new BufferedReader(isReader);
 }catch(Exception ex){
 ex.printStackTrace();
 }
 }

 public void run(){
 String message;
 try{

 while((message = reader.readLine()) != null){
 System.out.println("Read " + message);
 tellEveryone(message);
 }
 }catch(Exception e){
 e.printStackTrace();
 }
 }

 }


 public void go(){
 clientOutputStreams = new ArrayList();


 try{
 ServerSocket serverSock = new ServerSocket(5000);

 while(true){
 Socket clientSocket = serverSock.accept();
 PrintWriter writer = new PrintWriter(clientSocket.getOutputStream());
 clientOutputStreams.add(writer);
 //writer.println(clientOutputStreams);
 Thread t = new Thread(new ClientHandler(clientSocket));
 t.start();
 System.out.println("Got a connection!");
 }

 }catch(Exception exx){
 exx.printStackTrace();
 }
 }

 public void tellEveryone(String messages){
 Iterator it = clientOutputStreams.iterator();
 while(it.hasNext()){

 try{

 PrintWriter writer = (PrintWriter) it.next();
 writer.println(messages);
 writer.flush();
 }catch(Exception e){
 e.printStackTrace();
 }
 }
 }

 public static void main(String[] args){
 new Server().go();
 }

}

The entire Server code in all its Glory!

The entire Chat Application in its glory!

import java.io.*;
import java.util.*;
import javax.swing.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;

public class Client {

	JTextArea incoming;
	JTextField outgoing;
	JButton sendbutton;

	BufferedReader reader;
	PrintWriter writer;

	Socket sock;

	public void go(){
		JFrame frame = new JFrame("Client");
		JPanel mainpanel = new JPanel();

		incoming = new JTextArea(15,50);
		incoming.setLineWrap(true);
		incoming.setWrapStyleWord(true);
		incoming.setEditable(false);

		JScrollPane qScroller = new JScrollPane(incoming);
		qScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		qScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);

		outgoing = new JTextField(20);
		sendbutton = new JButton("Send");

		sendbutton.addActionListener(new SendButtonListener());

		mainpanel.add(qScroller);
		mainpanel.add(outgoing);
		mainpanel.add(sendbutton);

		setUpNetworking();

		Thread readerThread = new Thread(new IncomingReader());
		readerThread.start();

		frame.getContentPane().add(BorderLayout.CENTER, mainpanel);
		frame.setSize(400, 400);
		frame.setVisible(true);

	}

	public static void main(String[] args){

		Client client = new Client();
		client.go();
	}

	private void setUpNetworking(){

		try{

			sock = new Socket("127.0.0.1", 5000);
			InputStreamReader streamReader = new InputStreamReader(sock.getInputStream());
			reader = new BufferedReader(streamReader);
			writer = new PrintWriter(sock.getOutputStream());
			System.out.println("Networking established!!");

		}catch(IOException e){
			e.printStackTrace();
		}
	}

	public class SendButtonListener implements ActionListener{

		public void actionPerformed(ActionEvent e){
			try{
				writer.println(outgoing.getText());
				writer.flush();
			}catch(Exception ex){
				ex.printStackTrace();
			}

			outgoing.setText("");
			outgoing.requestFocus();
		}
	}

	public class IncomingReader implements Runnable{

		public void run(){
			String message;
			try{
				while((message = reader.readLine()) != null){
					System.out.println("read" + message);
					incoming.append(message + "\n");
					//incoming.setText(message + "\n");
				}
			}catch(Exception e){
				e.printStackTrace();
			}
		}
	}

}

The entire Chat Application in its glory!

A Simple Chat Server in Java using threads Part 1

The Client
———

The client side first. We import the necessary stuff  needed for this program. The java.net.* contains all
the necessary packages for the networking part. The swing and awt packages are for the GUI.

import java.io.*;
import java.util.*;
import javax.swing.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;

public class Client {

The JTextArea will be used to display all the chat proceedings in real time. The objective of this program is to have mutiple clients connect to a server and receive the information passed to them in real time. We make use of threads in this case.

JTextField is used for passing the chat comments.
JButton is ofcourse used for sending the message.

JTextArea incoming;
JTextField outgoing;
JButton sendbutton;

BufferedReader is used to buffer the inputstream from another source.
We use the PrintWriter to print to the socket. It is similar to using the system println function.

BufferedReader reader;
PrintWriter writer;

Sockets
——–
Sockets form the important part of this program. Simply put, it is an IP addreass with a port number. Now, port numbers vary from about 0 to 65535. It should be noted that the port numbers from 0 to 1023 are reserved and should not, unless for a reason, be used. In this example we will be using the port number 5000 to connect to the server.

Socket sock;

The function go()
—————–
This is the first method to be called. This does the following:
1. Sets up a GUI environment like I mentioned in previous posts.
2. Calls the setUpNetworking() function which will be explained later. Basically, it sets up the networking environment.
3. Most importantly, we start the threads, which I will explain.

public void go(){
JFrame frame = new JFrame("Client");
JPanel mainpanel = new JPanel();

incoming = new JTextArea(15,50);
incoming.setLineWrap(true);
incoming.setWrapStyleWord(true);
incoming.setEditable(false);

JScrollPane qScroller = new JScrollPane(incoming);
qScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
qScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);

outgoing = new JTextField(20);
sendbutton = new JButton("Send");

sendbutton.addActionListener(new SendButtonListener());

mainpanel.add(qScroller);
mainpanel.add(outgoing);
mainpanel.add(sendbutton);

setUpNetworking();

Now what this  does is set up a mainpanel which is JPanel. On it we add a JTextArea, which itself is added onto a JScrollPane as seen from the code. The different paramenters of this are set accordingly. The JButton is added and ofcourse, the ActionListener() for the button.

Thread readerThread = new Thread(new IncomingReader());
readerThread.start();

This is how a thread is created. Here we pass a new object of the class IncomingReader which implements the Runnable class, which I will explain in a moment.

frame.getContentPane().add(BorderLayout.CENTER, mainpanel);
frame.setSize(400, 400);
frame.setVisible(true);

}

These are just basic frame housekeeping stuff.

public static void main(String[] args){
Client client = new Client();
client.go();
}

The program begins here ofcourse. An object of the type client is created and the go() function is called.

private void setUpNetworking(){

try{

sock = new Socket("127.0.0.1", 5000);

This step creates a socket at the address “127.0.0.1” which is the localhost, ie, the same computer. And we select arbitary socket number of 5000. This number is known to the server.

InputStreamReader streamReader = new InputStreamReader(sock.getInputStream());

The InputStreamReader reads the bytes of data coming from the socket inputstream.

reader = new BufferedReader(streamReader);

This is then passed on to the BufferedReader object.

writer = new PrintWriter(sock.getOutputStream());

The PrintWriter object is finally responsible for putting the message onto the output stream.

System.out.println("Networking established!!");

}catch(IOException e){
e.printStackTrace();
}
}

Before I mention about the networking function, I will explain the concept of the try — catch block of code. Now, while running a code block, exceptions are bound to happen. If we know in advance, that a particular error is likely to happen at a place, we can place it in a try block. So what happens is that if any error occurs in this part will be caught by the catch() statement and then the housekeeping stuff inside the catch block executes. The whole idea of this is to make the program stop gracefully in case of an error.
We make the exception object print out the StackTrace in this case.

public class SendButtonListener implements ActionListener{

public void actionPerformed(ActionEvent e){
try{
writer.println(outgoing.getText());
writer.flush();

We push the content typed into the JTextField into the outputstream of the socket using the writer and
clear the buffer after every step.

}catch(Exception ex){
ex.printStackTrace();
}

outgoing.setText("");
outgoing.requestFocus();
}
}

Once you send the message, you clear the JTextField and then give the focus back to the JTextfield so that the user can type in agagin.

This is the ActionListener for the JButton Send.

public class IncomingReader implements Runnable{

public void run(){
String message;
try{
while((message = reader.readLine()) != null){
System.out.println("read" + message);
incoming.append(message + "\n");

}
}catch(Exception e){
  e.printStackTrace();
  }
 }
 }
}

This is an important part of the program. This class is passed into the thread as an object. This class implements the Runnable interface. Now, each time a thread is created, this class is called. For each Client object created, new copies or threads of execution of this same program is spawned from the existing main thread, which is the only case in a sequential program and they run independently of each other till they complete or the mother thread stops.

Here what we do is to read from the BufferedReader as and when it is not empty and then post in onto the console as well as onto the JTextField using the append function.

A Simple Chat Server in Java using threads Part 1

Data Structures using Java Part 11: Java Interfaces, Java Packages, Building packages, Compiling packing, Using packages

Java Interfaces
——————
Are public method prototype and behaviour. We make use of the “interface” keyword.
It is like an abstract class with two differences:
1. A class can inherit from only one class, but can “implement” as many interfaces you want.
2. A Java interface
cannot implement any methods at all.
nor cannot include any fields except “static final” constants
Only contains method prototype and constants.

//Nukeable.java
public interface Nukeable{
	public void nuke(); // no body
}

// in java.lang
public interface Comparable{
	public int compareTo(Object o);
}

public class SList extends List implements Nukeable, Comparable{
	// all that matters
	public void nuke(){
		head = null;
		size = 0;
	}
	
	public int compareTo(Object o){
		// code that retruns a number thats less than 0 if <0 and 0 if =0 and >0 if >0
	}
}

Nukeable n = new SList(); // correct!
Comparable c = (Comparable)n; // need to use a cast as some Nukeable are not Comparable
n.nuke();
if (c.compareTo > 0){
// do something
}

Arrays class in java.util sorts arrays of Comparable objects.

public static void sort(Object[] a){ }

Runtime error occurs if any item in a is not Comparable. An interface can have a subinterface and it can itself have sub interfaces.

//NOTE this!!
public interface NukeAndCompare extends Nukeable, Comparable{ }

Java Packages
—————
Package is a collection of classes, Java interfaces and subpackages.

Three benifits:
1. Packages can contain hidden classes not visible outside package.
2. Classes can have fields and methods visible inside the package only.
3. Different packages can have classes with same name.

Example: java.io standard library.

Using Packages
—————-
Fully qualified name:

java.lang.System.out.println();

import java.io.File; // can now refer to File class
import java.io.*; // refer to all things in io

Every program implicitly import java.lang.*

Also x.y.z.Classfile should be in x/y/z/Classfile.class

Building packages
——————

//list/SList.java
package list;

public class SList{
	
	SListNode head;
	int size;
}

//list/SListNode.java
package list;

class SListNode{ //"Package protection"
	Object item; //"Package protection"
	SListNode list; //"Package protection"
}

Package protection is between private and protected.

A class/variable has package protection is visible to any class in the same package.
But it is not visible at all outside the package. ie files outside that directory.
The files that are outside only see the public classes/methods inside the package.

Public class must be declared in a file named after the class. The “package” class can appear in any *.java file.

Compiling and running
———————–
Must be done from outside the package.

//How to compile?

javac -g list/SList.java
javac -g list/ *.java
javac -g heap / *.java / *.java // this takes care of dependancies also
// How to run?
java list.Slist 

The four levels of protection
——————————-

			in same package	         in a subclass	everywhere	
1. public 			x				x			x
2. protected		x				x
3. package		        x
4. private

Data Structures using Java Part 11: Java Interfaces, Java Packages, Building packages, Compiling packing, Using packages

Data Structures using Java Part 10: Inheritence, Constructors, invoking orverriden methods, protected keyword, dynamic method lookup, Abstract class


Inheritence
————-
TailList is a subclass of SList.
SList is the superclass of TailList.

A subclass can modify a superclass in three different ways:
1. It can declare new fields.
2. It can declare new methods.
3. It can override old methods with new implementations. It is not necessary to orverride all.

public class TailList extends SList{

	// the head and size is inherited

	private SListNode tail;

	// override the insertEnd method
	public void insertEnd(Object obj){
	// solution
	}

}

Inheritence and Constructors
——————————–
Java executes the TailList constructor, but first it executes SList() constructor.

public TailList(){
	//SList constructor is called

	//additional
	Tail = null;
}

Zero parameter constructor is called by default. To change:

public TailList(int x){
	super(x); // calls the super class constructor and must be executed FIRST.
	tail = null;
}

Invoking overridden methods
——————————-

public void insertFront(Object obj){
	super.insertFront(obj); // for the superclass and  not necessarly the first line.
	if(size == 1){
	tail = head;
	}
}

The “protected” keyword
—————————-

public class SList{

	protected SListNode head;
	protected int size;
}

Both “protected ” field and method is visible to the declaring class and to all its subclasses.
In contrast, “private ” fields are not visible to subclasses.

Dynamic method lookup
————————
For Java “Every TailList is an SList”.

SList s = new TailList(); // TailList is a subclass of SList and SList is not abstract
s.insertFront(obj);

Abstract class
—————-
A class whose sole purpose it to be inherited. This is an ADT. An abstract method lacks the implementation.

public abstract class List{

	protected int size;

	public int lenght(){
		return size;
	}

	public abstract void insertFront(Object obj);

}

List mylist;
mylist = new List(); //compile time error

A non abstract class may never
1. contain an abstract method.
2. inherit one without providing an implementation.

List mylist = new SList(); // correct!
mylist.insertFront(obj);

One list sorter can sort every kind of list.

public void listSort(List l){
//code
}

Subclasses of List: SList, DList,TailList
TimedList: record amount of time doint list operations
TransactionList: Logs all the changes on a disk for power outage.

Data Structures using Java Part 10: Inheritence, Constructors, invoking orverriden methods, protected keyword, dynamic method lookup, Abstract class