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
Advertisements
Linked Lists in Java

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

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 8: Heaps and Stack, Binary Search, Recursion, Scope, Parameter passing

The Stack and the Heap
————————–
The heap stores all objects, including arrays and all the class variables.
The stack stores all the local variables including parameters.

When a method is called Java creates a stack frame (or called an activation record). It stores the parameters and the local variables. The JVM maintains an entire stack of “stack frames”. When the method completes, its stack frame is erased. Most OS give enough space for a few thousands of stack frames.

Thread.dumpstack()
———————-
This method when called will print out the contents of the stack frame. Its present in the java.lang package and so doesnt need to be imported.

Parameter passing
——————–
In Java , the parameters are passed by value. That is they are copied.

class IntBox{

	static void donothing(int x){
		x = 2;
	}

	public int i;

	static void set3(Intbox ib){
	ib.i = 3;
	}

	static void badSet4(IntBox ib){
		ib = new IntBox(4);
		ib.i = 4;
	}
}

// called
	static void donothing(int x){
		x = 2;
	}

// calling
	int a = 1;
	donothing(a);

The variable a will be created in present stack frame. When the function donothing() is called, a new stack frame is created on top of the previous frame and the variable x resides in this frame. Note that no change happens to a after the function completes. The frame is erased once the function exits.

When the parameter is a reference, the reference is copied and not the object it is pointing to.

//called

	static void set3(Intbox ib){
	ib.i = 3;
	}

//calling
	IntBox b = new IntBox();
	set3(b);

In the local stack variable b is created. The object is created in heap with the variable i inside it. b points to object. set3() creates a parameter ib, both in new stack frame and then ib points to object pointed by b. The value of the object is changed by ib which is reflected on b, since both point to the same thing.

// called
	static void badSet4(IntBox ib){
		ib = new IntBox(4);
		ib.i = 4;
	}
//calling
	IntBox b = new IntBox();
	badSet4(b);

The difference here is that now a new object is created by the setBad() function and its value of ib is being set. The old heap object still retains its value. This happens to be a common programming error.

Binary Search
—————-
Used to search a sorted array. Suppose we want to search in a sorted int array. In this example , we try to find whether the variable “find” exists in the array, if so then return its array index. If not, return failure. This is going to be a predefined constant like FAILURE = -1. I have used a recursive algorithm.

Binary Search Procedure
// Binary Search
public static final int FAILURE = -1; // set as -1 because no index is less than 0 and final implies constant

public static int binarySearch(int[] i, int left, int right, int find){

	if (left > right)				// this is the base case; exit if the case.
		return FAILURE;

	int mid = (left + right)/2;          // find the middle element ; base case

	if (find = i[mid]){
		return mid;			// found!
	}else if (find < i[mid]){		// less implies the left subarray
		return binarySearch(i, left, mid -1, find);
	}else {					// more implies the right subarray
		return binarySearch(i, mid + 1, right,  find);
	}
	}
}

Recursion base cases:
1. if find = middle element: return index
2. if subarray is of length 0, nothing is there to search, return 0.

How fast is it?
Takes log n (base 2) recursive binarySearch calls.

Scope and Recursion
———————-
Scope of a variable : is portion of the program , actual lines of code, that can access the variable.
1. Class variables: (static fields) are in scope everywhere in the class except where shadowed by local variables. (like when using “this”)
2. Fully qualified class variable:For example “System.out” is not ambiguous. They are in scope everywhere in the class and are not shadowed. If public, they are in scope in ALL classes.
3. Instance variables: These are in scope in methods that are not static, except when shadowed.
4. Fully qualified instance variable: For example: “this.name” Same as 2.
5. Local variables: which includes parameters, only in scope in the block that defines them.

Data Structures using Java Part 8: Heaps and Stack, Binary Search, Recursion, Scope, Parameter passing

Data Structures using Java Part 7: Linked Lists Part 2 (Doubly Linked)

private field
————–
private field is invisible and inacessable to other classes.
Reasons:
1. To prevent data to be corrupted by other classes.
2. You can improve the implementation without causing the other classes to fail.

public class Date{

	private int day;
	private int month;

	public void setMonth(int m){
		month  = m;
	}

	public Date(int month , int date){
	// implementation and error checking code
	}
}
public class Evil{

	public void tamper(){

	Date d = new Date(10,10,2010); // this step is possible

	// these are not going to work!
	d.day =2000;
	d.setMonth(56);
	}
}

Interfaces
————
The interface of a class is made up of two things:
1. prototype for public methods and
2. the descriptions of the method behaviour.

Abstract Data Types(ADT)
——————————
ADT is a class(s) that has a well defined interface, but whose implementation details are firmly hidden from other classes.

Invarient
———-
Invarient is a fact about a data structure that is always true. (assuming there are no bugs). For example the “Date” object always represents a valid date.
Not all classes are ADTs. Some are just store data(no invarients).

The SList ADT
—————–

Another advantage of having a seperate SList class is that it enforces two invarients:
1. “size” is always correct.
2. list is never circularly linked.

Both of these goals are accomplised through simple Java mechanisms. Only the SList methods can change the lists.

SList ensures this:
1. The fields of the SList class are private. The “head” and “size” are private.
2. No method of SList returns an SListNode.

Doubly Linked Lists
———————

Doubly linked list

Inserting or deleting an element at the front of list is easy:

public void deleteFront(){
	if (head != null){
	head = head.next;
	size--;
	}
}

Inserting or deleting the item from the end of the list takes a lot of time in traversals.

public class DListNode{

	int item;
	DListNode next; // reference to the next node in list
	DListNode prev;// referencet to the previous node in the list

}

public class DList{

	private DListNode head; // points to start of the list
	private DListNode tail; // points to the end of the list
}

Insert and delete items at both ends in constant running time.
Removes the tail node (at least 2 items in DList):

tail.prev.next = null;
tail = tail.prev;

Sentinel
———
A special node that does not represent an item. It is to be noted that the sentinel node does not store an item.

Circularly linked Doubly linked list
————————————

 // no changes here
 public class DListNode{

	int item;
	DListNode next; // reference to the next node in list
	DListNode prev;// referencet to the previous node in the list

}

// changes here
public class DList{

	private DListNode head; // head will point to the sentinel
	private int size; // keeps track of the size of the list excluding the sentine.
}

DList invarients with sentinel:
——————————–
1. For any DList data structure d, d.head will never be null.
2. For any DListNode x, x.next is never null.
3. For any DListNode x, x.perv is never null.
4. For any DListNode x, if x.next is == y, then y.perv ==x.
5. For any DListNode x, x.prev ==y, then y.next ==x.
6. A DLists “size” field is number of DListNodes, NOT COUNTING sentinel. The sentinel is always hidden.
7. In empty DLists, the sentinels next and prev point to itselfs.

Data Structures using Java Part 7: Linked Lists Part 2 (Doubly Linked)

Data Structures using Java Part 6: Linked Lists Part 1

Lists
—–
Store a list of integers as an array.

Disadvantages:
1. Suppose you want to insert an item at beginning or middle of the list. This takes time propotional to the length of the array.
2. Arrays have a fixed length.

public class List{

	int[] a; // a reference
	int lastItem; // index to the last item of the list

	public List(){
	a = new int[10];
	lastItem = -1;
	}

	public void insertItem( int newItem, int location){ // inserts a new item at a location in the list
		int i;
		for(i = lastItem; i>= location; i--){  // this moves all the items in the list towards the right till the location is emptied
				a[i+1] = a[i];
		}
	a[location] = newItem; // puts the newItem value into the empty location slot
	lastItem++; // increment number of items
	}
}

Linked Lists ; A recursive data type
—————————————
1. A list that is made up of data structures called nodes.
2. Each node stores two things:
– an item
– a reference to the next node in the list

Singly linked list
public class ListNode{
	int item;
	ListNode next; // a reference called next pointing to next node in the list

}

// creating 3 different nodes
ListNode l1 = new ListNode();
ListNode l2 = new ListNode();
ListNode l3 = new ListNode();

// initialising values for items
l1.item = 10; // giving a value for item for l1
l2.item = 100;
l3.item = 1000;

//linking the nodes
l1.next = l2; // this links the lists
l2.next = l3;
l3.next = null; // l3 does not point to anything

Node operations
—————–

// the constructor for the ListNode
public ListNode(int item, ListNode next){

	this.item = item;
	this.next = next;
}

// for the last node
public ListNode(int item){
	this(item, null);
}

ListNode node1 = ListNode(7, new ListNode(0, new ListNode(6)));

Advantages over arrays
————————-
1. Inserting an item in the middle of the linked list takes constant amount of time if you have a reference to previous node.
2. Moreover, the list can keep growing until the memory runs out.

Inserting a new item after “this”

public void insertAfter(int item){

next = new ListNode(item, next); // the later "next" is the older value on whatever object we can like l2
}

l2.insertAfter(2);

The last statement creates a new node with the item value 2 and the next parameter is the next value of l2( old ) which points to l3. Now the new “next” value is assigned to the newly created node.

Disadvantages
—————
1. Finding the nth item of the linked list takes time propotional to the length of the list n, number of items in the list. With arrays you can do this in constant time.

// to find the nth item in a list
public ListNode nth( int location){

	if(position == 1){  // the current item
		return this;
	}else if ((position < 1) || ( next == null)){  // error checking
		return null;
	}else{
		// we will use recursion
		return next.nth(position -1); // -1 as we the list size keeps on decreasing
	}
}

ListNode l2 = l.nth(4);

Lists of objects
—————–
1. Reference any object by declaring a reference of type Object.

public class SListNode{ // a singly linked list

	public Object item;
	public SLinkNode next;
}

A List Class
————-
There are 2 problems with SListNodes:
1. Insert new item at the begining of the list.

x = new SListNode("Soap", x); // problem when two references to same node

2. How do you represent an empty list?

x = null; // runtime error if you try to call any method on x

Solutions
———-
1. Seperate SList class that maintains the head of the list.

public class SList{
	private SListNode head; // points to the beginning of the linked list
	private int size;  // keeps track of the number of SListNodes

	public SList(){ // initialisation
	head = null; // the idea of an empty list.
	size = 0;
	}

	public void insertFront(Object item){ // we now insert it here and not in SListNode
		head = new SListNode(item, head);
		size++;
 	}
}
Data Structures using Java Part 6: Linked Lists Part 1

Data Structures using Java Part 5: More on arrays, initialisers, function parameters, do loop, break ,continue and final

Automatic Array Construction
——————————–

int[][] table = new int[x][y];

1. Creates an array of x referecnces to array.
2. Creates x arrays of y int.

 

Initialisers
————

Human[] b = {amy, danny, Human(" Jacky")};
int[][] c = {{2,4,5},{45},{2,4,5,6},{1,3,},{x},{y+3, 4}};

int[] a,b,c; // specifies the type and all are reference arrays
int a[], b, c[][]; // a is 1D , b is just an int and c is 2D; proper C style
int[] a , b[]; // a is 1D and b is 2D

Array of objects
——————
When you create an array of objects, Java does not automatically create the objects for you. And you need to create a loop for the same.

Fraction[] f = new Fraction[5];
for (int i = 0; i<5; i++) {
	f[i] = new Fraction[i][6];
}

Main functions parameters
—————————-

class Echo{

	public static void main(String[] args ){
		for(int i =0; i< args.length; i++){
			System.out.println(args[i]);
		}
	}

}

1. String[] args consists of the arguments you type in at the unix prompt.
2. args.length gives the number of arguments.
For example if we type this in the unix prompt:

$ java Echo my name is Daniel

my
name
is
Daniel

Note that java Echo is not a part of the argument list.

do loops
——-
1. Executes the loop body at least once.

 do{
 s = keybd.readLine(); // read a line from the keyboard
 process(s); // do something
 }while(s.length > 0); //  if size of s is 0 , then exit the loop
 

There might be an ambiguity as in what to do if the user enter anything in the beginning. This will cause the process method to break down and ultimately an error occurs. This can be corrected by the following code:

The break and continue statement
————————————-
break statement always exits the innermost “switch” or loop enclosing the break.

 // method one
 s = keybd.readLine();
 	while(s.length > 0){       // process only if the length is greater than 0
 		process(s);
		 s = keybd.readLine();
 	}

Disadvantage:
1. Repeated code s = keybd.readLine()

 

 // method two: with the break statement
 while (true){

 	s = keybd.readLine();
 	if(s.length == 0)
 		break;

 	process(s);
 }
 

Disadvantage:
1. Obfuscated
2. Loop is not aligned with natural alignment

 

Continue
———
1. It only applies to loops
2. Doesnt exit the loop.
3. Another iteration my commence if condition of do/while/for loop is satisfied.

 loop:
 while(i < 9){
 	stuff:{
 		switch(s){
 		case 1: break;
 		case 2: break stuff; // breaks the loop and continues at statement 1
 		case 3: continue; // jumps out of switch but still inside while loop and so next iteration occurs
 		case 4: continue loop; // same as above

 		}
 		//statement 1
 	}
	//statement 2
 }
 

Constants
———–
“final” keyword – value that can never be changed.

BAD:

if (month == 2){ // if 2 represents something like a month february and it is difficult to change

GOOD:

 public static final int FEB =2; // change code only in one place
 if (month == FEB){
 }

For any array x, x.length is considered to be a final field and thus cannot be changed!

Data Structures using Java Part 5: More on arrays, initialisers, function parameters, do loop, break ,continue and final