+ All Categories
Home > Education > Javanotes

Javanotes

Date post: 12-May-2015
Category:
Upload: john-cutajar
View: 5,660 times
Download: 3 times
Share this document with a friend
Description:
Java Notes for computing course at junior college
Popular Tags:
260
A COURSE IN JAVA Cutajar & Cutajar © 2012
Transcript
Page 1: Javanotes

A COURSE IN JAVA

Cutajar & Cutajar © 2012

Page 2: Javanotes

The Introduction starts with giving a short definition of the terms used in object oriented programming. This is followed by a brief history and some good properties of Java.

The chapter then introduces the concept of Java programming, by explaining the various steps used to write a simple Java class. The concept of a class is described in detail.

Concepts of OOP

Page 3: Javanotes

Objects & Classes

To distinguish between an object and a class one may use the analogy of a mobile phone. When we speak of a class we speak of a type of object for example a class of a mobile, maybe a Nokia 370.

A Nokia 370 is not a distinct object – it has no actual colour or number. On the other hand when we speak of my mobile of type Nokia 370 we are specifying a distinct object. It‘s colour is black and the number is 7942816. This is an object - a specific mobile.

You can have many objects of the same class and each object we can call an instance of that class. Tom, Jerry, and Mary can each have a Nokia 370; each an instance of a Nokia 370.

The designer didn't design my mobile but designed the Nokia 370 of which my mobile is an instance. So in programming we design a class and then create new instances of that class.

Page 4: Javanotes

Abstraction

The essence of abstraction is to extract essential properties while

omitting inessential details.

To keep to our analogy, an abstraction can be considered as a

mobile without any details of how it functions.

All that I am concerned, is that my mobile behaves exactly like

any other mobile of its type, and knowing how to use one

enables me to use any mobile of that type since all I am

concerned is that it provide all facilities offered by a my mobile.

Page 5: Javanotes

Information Hiding

Information hiding is the principle of segregation of design

decisions in a computer program that are most likely to change,

thus protecting other parts of the program from extensive

modification if the design decision is changed.

The protection involves providing a stable interface which

protects the remainder of the program from the implementation

(the details that are most likely to change).

The user of the mobile is not concerned with the inner workings

of the mobile, but only to how to switch on the mobile and the

functions to use it.

Page 6: Javanotes

Encapsulation

The concept of encapsulation refers to

building a capsule, in this case a

conceptual barrier, around some

collection of things.

All functions of the mobile are

encapsulated within the case.

This makes the object much more easy

to handle as identical functions are

grouped together in a single mobile.

Page 7: Javanotes

Methods & Data Values

An object is composed of data values and methods.

Methods are ways to use an object and they normally receive or return a value to or from the object. In our mobile analogy, a subscriber uses the mobile by choosing the function and pass to it, or retrieves from it, the required data

Data values are values contained within the object. They are the properties of that object. These can be instance data values which belong to only one particular instance, or a class data value belonging to all objects of the same class.

Methods act on these data values. Methods which access data values are called accessor methods whilst those which change it are called mutator methods, just like the functions of your mobile.

Page 8: Javanotes

Java’s Past and Present

The Java language was originally created to solve the

problems surrounding personal digital assistants (PDAs) and

consumer electronic products, such as microwaves and toaster

ovens. The language had to be robust, small, and portable.

However, the Java team discovered that Java‘s design made it

ideal for another purpose: programming on the Internet. In

1993, the World Wide Web was gaining popularity, with its

myriad platforms and operating systems, and it desperately

needed a platform-independent language—so Java found a

new home.

Page 9: Javanotes

Java Is Platform-Independent

The Java language was designed specifically to be platform-independent.

This means that programs written in Java can be compiled once and run on

any machine that supports Java. So, what exactly does platform-

independence mean, and how does it differ from what was available

before Java?

Traditional compiled programming languages are compiled to machine-

level binary code that is, of course, specific to the machine or platform on

which it is compiled. The advantage is that the compiled binary runs quickly

because it is running in the machine‘s native language. The disadvantage is

that a program written in a traditional language has to be recompiled to

binary code for each different hardware platform before it can be run on

that machine.

On the other hand, traditional interpreted programming languages are

machine-neutral and can be run on various platforms, they generally run

much slower than compiled applications.

Page 10: Javanotes

The Java Virtual Machine (JVM)

Java has incorporated the best of both worlds. The Java team

created a platform-specific layer, called the Java Virtual

Machine (Java VM), which interfaces between the hardware and

the Java program. When you install a Java-capable browser on

your computer, for example, a copy of the Java interpreter is

also installed, which is what enables your browser to execute

Java applets and your system to run standalone Java programs.

Java interpreter and Java runtime are alternative terms for the

Java Virtual Machine (VM).

The Java VM presents the same interface to any applets that

attempt to run on the system, so to applets, all machines look the

same. The applet itself is compiled into a form of interpretable

code called Java bytecodes. This special form of code can be

run on any platform that has the Java VM installed.

Page 11: Javanotes

The Bytecode

Bytecodes are a set of instructions that are similar to machine code but are

not processor-specific.

They are interpreted by the Java VM. Sun‘s trademark phrase ―write once,

run anywhere‖ is the promise that is fulfilled by Java.

This, above all other features of the language, is what makes it so essential

for interactive

Web programming. It makes code much safer as it interacts only with the

JVM.

Page 12: Javanotes

Java Is Object-Oriented

Java is a real object-oriented language, which enables you to

create flexible, modular programs.

It includes a set of class libraries that provide basic data

types, system input and output capabilities, and other utility

functions.

It also provides networking, common Internet protocol, image

handling, and user-interface toolkit functions.

Java‘s object classes provide a rich set of functionality, and

they can be extended and modified to create new classes

specific to your programming needs.

Page 13: Javanotes

Java Is Easy to Learn

Among the original design goals of the Java team members

was to create a language that was small and robust. Because

they started from scratch, they were able to avoid some of the

pitfalls of other more complex languages. By eliminating things

such as pointers, pointer arithmetic, and the need to manage

memory explicitly, the Java development team made Java one

of the easiest languages to learn. However, you can still do

anything in Java that you can do in traditional languages. If

you have previously used a high-level object-oriented

programming language, such as C++, much of Java will look

familiar to you.

Page 14: Javanotes

My First Java Program

import javax.swing.*;

/*

My First Java Program:

Displaying a Window

*/

public class MyFirstProgram {

public static void main (String[ ] args) {

JFrame tieqa;

tieqa = new JFrame( );

tieqa.setSize(300, 200);

tieqa.setTitle(―Hello Cutajar‖);

tieqa.setVisible(true);

}

}

filename must be saved as MyFirstProgram.java

comment

import required package

class definition starts here main method starts

declare object of given class

create a new object

call methods of

class JFrame

main method ends

class definition ends

block

use methods

on object

indent

Page 15: Javanotes

/* Comments */

/* This is a multi-line comment

and ends with */

// This is a single line comment and ends with a return

Everything enclosed within (/*) and (*/) is a comment and is

ignored by the compiler.

Another way to write a single line comment is by starting the

line with a double slash (//), everything until the end of line is

ignored.

Special comments enclosed in (/**) and (*/) are used in

documentation. These are called JavaDoc comments

Page 16: Javanotes

The Concept of a Class

The example is a class which comprises:

one or more import statements to import libraries (packages)

containing classes of objects already defined

a method called main() having some parameters

a method has a header conveying the method‘s name (main)

a block

a block {enclosed in braces} comprises:

a set of declarations (what you need)

a set of statements (what to do)

each import, declaration or statement end with a semicolon (;)

a class

a method

a block

Page 17: Javanotes

Object Declaration

When declaring an object we are actually giving a name to

an object of that class.

JFrame tieqa;

class must be already defined

class names start with

uppercase

object names start with

lowercase

tieqa null

JFrame is defined in

javax.swing

Page 18: Javanotes

Object Creation

When we create an object

Example: tieqa = new JFrame();

we are effectively reserving memory space for an object. This

is when the object really comes in existence.

tieqa = new JFrame( );

calling the creator of

JFrame tieqa

JFrame

Page 19: Javanotes

Methods - Calling Methods

In Java we call methods on objects. So we use the name of the

object and the method we want to use of that object

separated by a dot. Note that since we call the method of an

object we are only effecting that particular instance. ( We will

see later some exceptions on static classes).

tieqa.setVisible (true);

name of

object parameters to send to method

name of

method

the

dot

account.deposit( 200.0 ); student.setName(“john”);

myMobile.addContact(“maria”);

Page 20: Javanotes

Method Declaration

When declaring a class the following statements must be

included. This is the main method of which one and only one is

needed for a program to execute.

public static void main ( String args[ ] ) {

access

modifier

scope

modifier return

type

method

name parameters block start

optional

public void deposit ( float amount) { balance = balance + amount;

}

Page 21: Javanotes

Naming

In the example class illustrates several names

invented by the programmer to identify

classes, objects and variables in general.

Such names are also called identifiers

These identifiers :

cannot be Java keywords:

cannot contain punctuation marks or spaces

must not start with a numeral.

My Window 1stVariable

case

Page 22: Javanotes

Naming Conventions

It is a common convention to name objects starting with a lower

case letters

We use an uppercase letter to separate words in the identifier.

On the other hand the name of the classes normally start with

an Uppercase letter.

Java is case-sensitive, meaning that lowercase letters and

upper-case letters are totally different letters.

You cannot name two different things with the same name:

myFirstWindow

tieqa

JFrame

Number and number are different

JPanel tieqa;

JFrame tieqa;

Page 23: Javanotes

This section introduces the building blocks of a program.

It introduces the concepts of primitive and non-primitive

(object) variables, their properties and their behaviour.

The operations among these variables are analysed

here, together with some new related pre-defined

classes.

The concept of constants is also discussed

JAVA Components

Page 24: Javanotes

Variables

A variable is an entities that can hold a value.

Before it can be used it must first be declared.

A variable has four properties:

An Address,

A memory location to store the value,

whose storage capacity depends on

the type of data to be stored,

The type of data stored in the

memory location, and

The name used to refer to the

memory location. (following the same

naming rules already discussed).

Page 25: Javanotes

Primitive Data Types

Primitive Data Types

Numeric

Integers

byte

short

int

long

Reals

float

double

char

boolean

Page 26: Javanotes

Sizes and Ranges of Variables

Declare the type of a

variable only once, as long

as its scope hasn't ended

Variables can be declared

anywhere in the program

int i, j, k; float numberOne, numberTwo; long bigInteger; double bigNumber; int count = 10, height = 34; numberOne = 3.45F;

i = 45;

Page 27: Javanotes

Assignment Operators

The assignment operator in Java is denoted by a single equals sign:

The variable on the left of the equals sign takes the resulting value

of the evaluation of the expression on the right.

The syntax is: <variable name or identifier> = <expression> ;

Normally on the left of the expression is the name of a variable

and on the right evaluates to a value which is assigned to the

variable. The left hand is called l-value.

In Java the overall result of the RHS expression is returned, allowing

the LHS to be assigned too as follows:

Page 28: Javanotes

Other Assignment Operators

There are also other assignment operators:

Page 29: Javanotes

Mixed Types Expressions

When terms of an expression are of different types, the

processor ‗coerces‘ values to a consistent type.

Coercion may cause a short to become long. (promotion) or a

long into a short (demotion).

If you wish to override coercion you may include a cast to

specify the precise promotion or demotion required.

This expression is called a mixed expression:

float x; int y;

x*y

Page 30: Javanotes

Automatic Promotion

The data types of the operands in mixed expressions are

converted, based on the promotion rules.

The promotion rules ensure that the data type of the

expression will be the same as the data type of an operand

whose type has the highest precision.

Page 31: Javanotes

Explicit Type Casting

Instead of relying on the promotion rules, we can make an

explicit type cast by prefixing the operand with the data type

using the following syntax: (<data type> ) <expression>

(float) x / 3

(int) (x / y * 3.0)

Convert x and result to float

Convert result to int

Page 32: Javanotes

Implicit Type Casting

Consider the following expression:

The result of 3 + 5 is of type int. However, since the variable

x is double, the value 8 (type int) is promoted to 8.0 (type

double) before being assigned to x.

double x = 3 + 5;

int x = 3.5;

Demotion is not allowed higher precision

Page 33: Javanotes

boolean

Another primitive data types in Java is boolean which has

only two possible values: true or false.

Use this data type for simple flags that track true/false

conditions.

This data type represents one bit of information, but its "size"

isn't something that's precisely defined.

boolean found = false;

Page 34: Javanotes

Enumerated Data Types

An enum type is a kind of class definition.

The possible enum values are listed in the curly braces,

separated by commas.

By convention the value names are in upper case as are

actually constants.

public enum Shape { RECTANGLE, CIRCLE, LINE }

Page 35: Javanotes

chars

The char data type is a single 16-bit Unicode

character.

Note that the single apostrophes delimit a

character. The double quotes (―) delimit a string

of characters.

Addition (+) between characters and strings

produces a concatenation and is stored in a

string

Note the difference

between 1 and „1‟

The code of „1‟ is 49 and not 1

String s = „A‟ + „B‟

Page 36: Javanotes

Character order

Characters in java have an ordinal value, thus there is an order

between them:

This means that you can even compare characters between

them.

Page 37: Javanotes

Strings

A string constant consists of a sequence of characters separated by double

quotes. There are close to 50 methods defined in the String class.

Note that a String is not a primitive data type but a class, and likewise

behaves like one. We say that Strings are immutable (cannot change value).

Notice the difference between primitive data types like strings. In primitive

data type the contents of the variable is the value, while in referenced data

type the contents is a pointer (address) of the location where the object

starts.

String name;

name = new String(“Johnny Java”); name null

name J o h n n y J a v a

index starts

at 0

pointer to where

string starts

Page 38: Javanotes

The String Class

A very commonly used class of the java.lang package is the

Sting class. Note that the java.lang package doesn't need to

be imported as it is imported directly by default by java.

There are various methods defined in the String class, to

mention a few, for an object str of class String:

str.substring(i,j) will return a new string by extracting characters of str

from position i to j-1 where 0 <= i < length of str, 0 < j <= length

of str, and i <=j.

str.length() will return the number of characters in str.

str.indexOf(substr) will return the first position substr occurs in str.

Page 39: Javanotes

Primitive Data Types

Numerical data , boolean and chars are called primitive data types.

For Primitive Data Types:

1. Allocate memory for variables.

2. Values are placed in the memory locations of the variable

3. If one of them say firstNumber gets reassigned the new value will overwrite the

old one. The value of 234 is overwritten by 187

int firstNumber; int secondNumber; firstNumber = 234; secondNumber = 87;

firstNumber = 187;

firstNumber

secondNumber

firstNumber 234 secondNumber 87

firstNumber 187

Page 40: Javanotes

Referenced Data Types

Objects (including Strings) are called reference data types, because their

contents is an addresses that refers to a memory locations where the objects

are actually stored.

For Objects:

1. Allocate memory for variables.

2. An object is created and its address is stored in the variable to point at it.

3.The reference to another object overwrites the reference in customer.

4. The reference in customer is assigned to client. So both point at the same object

Customer customer, client; customer = new Customer(“John”); customer = new Customer(“Mary”); client = customer;

customer J o h n J o h n

M a r y

customer

client

customer M a r y

client

customer

Page 41: Javanotes

Wrapper Classes

A wrapper is a class that contains data or an

object of a specific type and has the ability of

performing special operations on the data or

object.

Most common wrapper classes are for the

primitives.

Note that since wrapper classes are classes in all

effects, by convention they start with uppercase.

Reasons for wrapper around the primitives:

Converting from character strings to numbers

and then to other primitive data types.

A way to store primitives in an object.

A way of passing primitive data types by

reference.

Primitive Wrapper

boolean Boolean

byte Byte

char Character

double Double

float Float

int Integer

long Long

short Short

void Void

Double myDouble = new Double("10.5");

Page 42: Javanotes

Autoboxing

Autoboxing, introduced in Java 5, is the automatic conversion

the Java compiler makes between the primitive (basic) types

and their corresponding object wrapper classes (eg, int and

Integer, double and Double, etc).

The underlying code that is generated is the same, but

autoboxing provides a sugar coating that avoids the tedious

and hard-to-read casting typically required by Java

Collections, which can not be used with primitive

Double myDouble = 10.5;

Page 43: Javanotes

Converting Back to Primitives

Here are some examples to convert back to basic types

Wrapper class Method Example (for converting back to primitives)

Integer parseInt Integer.parseInt(“25”) gives 25

Integer.parseInt(“25.3”) gives an error

Long parseLong Long.parseLong(“25”) gives 25L

Long.parseLong(“25.3”) gives an error

Float parseFloat Float.parseFloat(“25.3”) gives 25.3F

Float.parseFloat(“abc”) gives an error

Double parseDouble Double.parseDouble(“25”) gives 25.0

Double.parseDouble(“abc”) gives an error

Page 44: Javanotes

Arithmetic Operators

We have already used and seen some of these as they are the

basic arithmetic operations whose function is intuitive.

Page 45: Javanotes

Increment and Decrement

Java has two special operators for incrementing or

decrementing a variable by one.

These may either be prefix (before the variable) or postfix

(after the variable).

if you include i++ as a term of a larger expression, the original

value of i is used and afterwards incremented or decremented in

case of i--

if you include ++i or --i as a term of a larger expression, the new

value of i is used.

Page 46: Javanotes

Comparison

Each comparison using one of the six infix operators below will

produce a boolean result of true or false.

Evaluation is from left to right and is short circuit.

Short circuit means that if the operation is an ―and‖ and the first

clause evaluates to false, the rest of the clauses are not

evaluated.

Similarly if the operation is an ―or‖ and the first clause is true

the rest are omitted.

Page 47: Javanotes

Chaining Logical Conditions

NOT The logical not is a prefix operator.

AND & OR

The truth tables of the && (and) and the ||

(or) operations shown below indicate that the

two operations are commutative. For example

(i && j) produces the same result as (j && i)

int i = 10, j = 28; boolean valid;

valid = ((i < 12) && (j <15));

Page 48: Javanotes

Conditional Assignment Operator

The conditional assignment (ternary) operator provides an in-

line if/then/else.

If the condition is true, the expression after the ―?‖ is evaluated and

returned as a result of the statement.

If the condition is false, the expression after the ―:‖ is evaluated and

returned as a result of the statement.

Page 49: Javanotes

Bitwise Operators

Bitwise operators are used only with operands of integral

types

Page 50: Javanotes

Example of Bitwise Operators

Page 51: Javanotes

Precedence and Associativity

Precedence of Operators

Java treats operators with different

importance, known as precedence.

There are in all 15 levels of

precedence. In general, the unary

operators have a higher precedence

over the binary operators and

parentheses can always be used to

improve clarity in the expression.

Associativity of Operators

For two operators of equal precedence

a second rule, ―associativity‖ applies.

Associativity is either ―left to right‖ (left

operator first) or ―right to left‖ (right

operator first):

Page 52: Javanotes

Constants

We can change the value of a variable. If we want the value

to remain the same, we use a constant.

To specify the exact type of literal constants, one can use the

L,F and D or l,f and d to define the precision for numerals.

We then use the reserved keyword final to lock it.

final double PI = 3.14159D; final int MONTH_IN_YEAR = 12;

final short FARADAY_CONSTANT = 23060;

As a convention we use uppercase letters

separated by underscores for

constants

Page 53: Javanotes

The Math Class

The Math class in the

java.lang package

contains class methods for

commonly used

mathematical functions.

Most methods of the Math

class are static and

therefore there is no need

to instantiate any new

object of the Math class

before using it.

Most Math class methods

generate a double type, so

pa attention to precision

errors

Method Description

abs(a) Absolute value of a

exp(a) Natural number e raised to the power of a.

log(a) Natural logarithm (base e) of a.

floor(a) The largest whole number less than or equal to a.

max(a,b) The larger of a and b.

min(a,b) The smaller of a and b

pow(a,b) The number a raised to the power of b.

sqrt(a) The square root of a.

sin(a) The sine of a. (Note: all trigonometric functions are

computed in radians) Similarly cos and tan

random() Returns a double value with a positive sign, greater

than or equal to 0.0 and less than 1.0.

round(a) Returns the closest integer value, if a is double it

returns long, if float it returns int

toRadians(a) Converts the value of a in degrees to radians

//Generate a random number between 1 and 100

int r = (int)Math.round(1+Math.random()*99);

Page 54: Javanotes

Op Summary

Here is a summary of the

operators used in Java.

B.E.D.M.A.S

In most simple cases it easier

to remember the precedence

of operators using the slightly

modified BEDMAS (Brackets

Exponent Division

Multiplcation Addition and

Subtraction). As a general

rule, instead of relying on

memory, in case of doubt, use

the brackets to make the

precedence you desire.

Page 55: Javanotes

Example

public class Matematika{ public static int random(int startRange, int endRange){ int answer = (int) (startRange+Math.random()*(endRange-1)); return answer; } public static int power(int base, int exponent){ int answer = (int)Math.round(Math.exp(Math.log((double)base)*exponent)); return answer; } public static boolean isEven(int n){ return (n%2) == 0; } public static double sin(double degrees){ double radians = degrees*2*Math.PI/360D; double answer = Math.sin(radians); return answer; }

}

Page 56: Javanotes

Example main program and Output

public class UseMatematika{ public static void main (String args []){ int number1 = 1; int number2 = 6; int number3 = 2; int dice = Matematika.random(number1,number2); System.out.println("The first roll of the die gave: "+dice); double result = Matematika.power(number3, number2); System.out.println(number3+" to the power of "+number2+" = "+result); System.out.println("Sine of 30 degrees is: "+Matematika.sin(30D)); System.out.println(number1+" is even ? "+Matematika.isEven(number1)); }

}

Page 57: Javanotes

In this section we start constructing our own classes.

First we discuss the standard input and standard output

which we need throughout the course to make our

programs interactive.

Secondly we deal with how classes are defined. Various

aspects of the data and methods will be described,

among which the most important is the constructor.

Programming Elements

Page 58: Javanotes

The Standard Input – The Keyboard

The technique of using System.in to input data is called

standard input. We can only input a single byte using System.in

directly, so to input primitive data values, we use the Scanner

class. Method Example

nextByte( ) byte b=kb.nextByte( );

nextDouble( ) double d=kb.nextDouble( );

nextFloat( ) float f=kb.nextFloat( );

nextInt( ) int i=kb.nextInt( );

nextLong( ) long l=kb.nextLong( );

nextShort( ) short s=kb.nextShort( );

next() String str=kb.next();

useDelimiter(String) kb.useDelimiter(“\n”);

import java.util.*; … Scanner kb; kb = new Scanner(System.in);

int num = kb.nextInt();

Page 59: Javanotes

The Standard Output – The Monitor

Using System.out, we can output multiple lines of text to the

standard output window.

We use the print method to output a value to the standard

output window. The print method will continue printing from the

end of the currently displayed output.

We use println instead of print to skip a line.

int x = 123, y = x + x; System.out.println(" Hi John”); System.out.print( " x = “ ); System.out.println( x ); System.out.print( " x + x = “ ); System.out.print( y ); System.out.print(“\n”);

System.out.println( " THE END“ );

Page 60: Javanotes

Defining a New Class

Learning how to define our own classes is the first step toward

mastering the skills necessary in building large programs.

Classes we define ourselves are called programmer-defined

classes.

{

}

public class

imports

class Name

comments

Data Members

(fields)

Member

Methods

Page 61: Javanotes

Class Example

import java.util.*; /** * Account Class */ public class Account{ private String name; private String idCard; private float balance; public Account(String n, String id, float b){ name =n; idCard = id; balance = b; } public void deposit(float amount){ balance += amount; } .........

}

Member

Methods

Data Members

(fields)

special method (The Constructor ) which builds the object on

instantiation

imports

class Name

comments

Page 62: Javanotes

Organizing Classes into a Package

For a class A to use class B, their bytecode files must be

located in the same directory. This is not practical if we want to

reuse programmer-defined classes in many different programs

The correct way to reuse programmer-defined classes from

many different programs is to place reusable classes in a

package.

A package is a Java class library.

import PackageA.*; public class UsePackage{ public static void main (String args[]){ MyFrame newFrame = new MyFrame(); newFrame.setVisible(true); }

}

Page 63: Javanotes

Compiling and CLASSPATH

CLASSPATH

Specifying where to search for additional libraries in Windows is easily

done by setting the environment variable CLASSPATH, which Java uses

to see where it should find Java programs and libraries.

Account.java BankManager.java

Account.class BankManager.class

Compilation

into bytecode

to JVM +

Page 64: Javanotes

Parameters

An argument or actual parameter is a value we pass to a

method.

A formal parameter is a placeholder in the called method to

hold the value of the passed argument.

An actual parameter is the actual value passed by the caller

program

public void deposit(float amount){ balance += amount;

}

a1234.deposit(500);

actual parameter formal parameter

in

Account calling method

Page 65: Javanotes

Matching Actual and Formal Parameters

The number of arguments and the number of parameters must

be equal

Formal and actual parameters are paired left to right, and the

names of the formal and actual parameters are by no means

important for matching.

Each matched pair must be assignment-compatible (e.g. you

cannot pass a double argument to a int parameter)

When we are passing primitive data values, the parameter

passing is by value, so the receiving side cannot alter the

values for the passing side.

When more than one parameter is passed, they are separated

by a comma (,)

Page 66: Javanotes

Pass-By-Value (by Copy)

The actual parameter (or argument expression) is fully evaluated and the

resulting value is copied into a location being used to hold the formal

parameter's value during method execution. That location is typically a

chunk of memory on the runtime stack for the application (which is how Java

handles it),

public float add(float a, int b){ return a+b;

}

float x = 25.5F

Item.add(x, 25);

25.5

25

25.5

25

a

b

x

no name

literal constant

in main

in

object

matched

by position

memory space of

main

memory space

of object

Page 67: Javanotes

Pass-By-Reference

As we can pass int and double values, we can also pass an

object to a method. When we pass an object, we are actually

passing the reference (address) of an object. This means a

duplicate of an object is NOT created in the called method, so

object parameters are passed by reference.

public void add(Student a){ a.getName();

}

Student s = new Student();

klassi.add(s);

a

s

Student

memory space

of main

Page 68: Javanotes

Note on Primitive Parameter Passing

Primitive data arguments are passed to a method by using the pass-by-

value scheme.

Arguments are matched to the parameters from left to right. The data type

of an argument must be assignment-compatible with the data type of the

matching parameter.

The number of arguments in the method call must match the number of

parameters in the method definition.

Parameters and arguments need not have to have the same name.

Local copies of values passed by reference as parameters, which are

distinct from arguments, are created even if the parameters and arguments

share the same name.

Parameters are input to a method, and they are local to the method.

Changes made to the parameters will not affect the value of corresponding

arguments

Page 69: Javanotes

Access Modifiers

The access modifiers public and private designate the accessibility of data

members and methods.

If a class component (data member or method) is declared private, client

classes cannot access it.

If a class component is declared public, client classes can access it.

Internal details of a class are declared private and hidden from the clients.

This is information hiding.

If none of this is declared, the method or data member becomes package

friendly and can be accessed only from classes in the same package.

class Service { public int memberOne; private int memberTwo; public void doOne() { … } private void doTwo() { … }

}

… Service obj = new Service(); obj.memberOne = 10; obj.memberTwo = 20; obj.doOne();

obj.doTwo();

Page 70: Javanotes

Guideline for Access Modifiers

Declare the class and instance variables private.

Declare the class and instance methods private

if they are used only by the other methods in the

same class.

Declare the class constants public if you want to

make their values directly readable by the client

programs. If the class constants are used for

internal purposes only, then declare them

private.

Another access modifier is protected. We will

see this one after treating inheritance, as it is

visible by subclasses which inherit the class.

Service +memberOne -memberTwo +doOne()

-doTwo()

private gets (-)

public gets (+)

Class Diagram

Page 71: Javanotes

Static or Dynamic

Instance methods or variables are associated with an object

and methods use the instance variables of that object. This is

the default.

Static methods use no instance variables of any object of the

class they are defined in.

If you define a method to be static, you will be given a rude

message by the compiler if you try to access any instance

variables. You can access static variables, but except for

constants, this is unusual. Static methods typically take all their

data from parameters and compute something from those

parameters, with no reference to variables.

Page 72: Javanotes

Typical Static Methods

Static methods typically do some kind of generic calculation.

A good example of this are the many utility methods in the

predefined Math class.

In any program there is only one version of a static method or

variable whilst in dynamic ones there is a new version every

instance created. Thus on static methods there is no need to call

the new statement in the client class as in dynamic classes.

public class Maths{ ... public static double cube(int x) { return (x*x*x); }

...

double result = Maths.cube(3);

no need to create a new object but use the class directly since method

is static

Page 73: Javanotes

Class Variables and Constants

Class Constants

provide a meaningful description of what the values stand for:

number = UNDEFINED; is more meaningful than number = -1;

provides easier program maintenance. We only need to change the

value in the constant declaration instead of locating all occurrences of

the same value in the program code.

Class Variables

Class variables are there to keep a overall copy of a value shared

among all objects of the same class, say the total number of objects

created, or the sum of money gained from all objects of a vending

machine.

private static final int MAX_NUMBER=6;

caps for constants

private static int minimumBalance;

lower for variables

Page 74: Javanotes

Class Example – Complex Number

We are used to real numbers, but when we

get to the square root of a negative number

we go in another dimension called the

imaginary numbers. Simply said we denote

sqrt(-1) = i. Thus sqrt(-9) becomes 3i.

A complex number consists of two parts a

real part and an imaginary part. To keep

things simple we shall represent these as

integers.

Suppose we want to create a new data type

in the form of a class to represent complex

numbers.

I

R

Page 75: Javanotes

The Data Members

First of all we need to define the data required for the

class, namely two integers, one for the real part and

another for the imaginary part.

It is good practice to declare these as private, so that

they are not directly accessible from outside the object.

Methods on the other hand are declared as public so

that the users of this class can communicate with them.

So we begin by declaring the two required fields

Since only methods within the object have access to

these, any bug within their value can be attributed only

to the member methods.

private int real;

private int img;

real

img

member

methods

Page 76: Javanotes

The Constructor

The constructor is a special member method which initialises an

object when it is created.

We limit, for the time being to set all fields to zero.

The constructor has always the same name as the class and has

no return type. Normally be implement this method as the first

method in the class.

If the constructor is not implemented specifically by the

programmer, will be implemented by Java, resetting all data

members. – The default Constructor public Complex(){ real = 0; img = 0;

}

Page 77: Javanotes

The Member Methods

These are methods that communicate with the external

environment and act upon the data members of the object.

Note that the constructor does not have a return type. This is

the only method not to have a return type.

Nearly all classes have setter (mutator) and getter (accessor)

methods to set the values of their private data members.

public void setValue(int r, int i){ real = r; img = i; }

public void setReal(int r){ real = r; } public void setImaginary(){ img = i;

}

public void getImaginary(){ return img; } public int getReal(){ return real;

}

Setter (mutator) methods Getter (accessor) methods

Generic methods

Page 78: Javanotes

Implementation

/**

* Main Class for complex numbers

*/

public class Roots{

public static void main (String args[]){

// Declare and instantiate

Complex number1;

number1 = new Complex();

// Declare and instantiate again

Complex number2 = new Complex();

// Set their value

number1.setValue(2,4);

number2.setValue(5,3);

// Display the two numbers

System.out.println("Number 1 = " +

number1.getReal() + " + " + number1.getImaginary()+"i");

System.out.println("Number 2 = " + number2.getReal() + " + " + number2.getImaginary()+"i");

}

}

/** * Class to represent a complex number */ public class Complex { // The Real Part of the Complex Number private int real; // The Imaginary Part private int img; // The Constructor (Initialiser) public Complex(){ real = 0; img = 0; } // Set the value of the complex number public void setValue(int r, int i){ real = r; img = i; } // Get the real value public int getReal(){ return real; } // Get the imaginary part public int getImaginary(){ return img; }

}

1 1

1

2 2

3

4

3

4

Page 79: Javanotes

Local Variables

Local variables are declared within a method declaration and

used for temporary services, such as storing intermediate

computation results.

Global Variables are declared outside all methods and can

be seen anywhere within the class.

It is good practice to use local variables as much as possible.

local variable

public double convert(int num) { double result; result = Math.sqrt(num * num); return result;

}

Page 80: Javanotes

Locals, Parameters & Data Members

An identifier appearing inside a method

can be a local variable, a parameter, or a

data member.

The rules are:

If there‘s a matching local variable

declaration or a parameter, then the

identifier refers to the local variable or the

parameter.

Otherwise, if there‘s a matching data

member declaration, then the identifier

refers to the data member.

Otherwise, it is an error because there‘s no

matching declaration.

Local variables and parameters cannot have

the same name.

class CD { private int n; private String artist; public CD(String n1, int n){ String ident; artist = n1; this.n = n; ident = artist.substring(0,2) } ... }

1 2

3 4

5

3

4

2

1

5

Page 81: Javanotes

“this” Keyword

If a parameter or local variable

have the same name as a data

member, they hide the global

variable.

Thus a reference to that name

will involve only the local

variable or parameter.

To overcome this, the keyword

―this‖ is used to refer to the

global variable.

―this‖ alone refers to the

constructor of the class.

public Circle(){ this(0D);

}

:Student

this

Page 82: Javanotes

Method Overloading

The Java programming language supports overloading methods, and Java

can distinguish between methods with different method signatures.

This means that methods within a class can have the same name if they have

different parameter lists.

Overloaded methods are differentiated by the number or the type of the

arguments passed to the method.

You cannot declare more than one method with the same name and the

same number and type of arguments, because the compiler cannot tell them

apart.

The compiler does not consider return type when differentiating methods, so

you cannot declare two methods with the same signature even if they have

a different return type.

Page 83: Javanotes

Overloading Example

In this code sample, draw(String

s) and draw(int i) are distinct

and unique methods because

they require different argument

types.

Note that a method with a

signature of:

public int draw(int i){

is not permitted because it

distinguishes itself from another

method only on the return type

public class DataArtist { ... public void draw(String s) { ... } public void draw(int i) { ... } public void draw(double f) { ... } public void draw(int i, double f) { ... }

}

Page 84: Javanotes

Constructor Overloading

The constructor of the class can

be overloaded as all other

methods, and it is normal

practice to provide more than

one constructor method.

this can also be used to call a

different overloaded

constructor of the same object..

Pay Attention: The call to this in

this case must be the first

statement in the constructor.

Circle circle1 = new Circle(3.5d); Circle circle2 = new Circle(); public class Circle{ private double radius; ... public Circle(){ radius = 0; } public Circle(double r){ radius = r; }

}

1

2

2

1

Page 85: Javanotes

Overloading Complex Constructor

Now that we have other tools at hand we can consider some

modifications to the Complex Numbers class implementation.

First we use the conditional assignment to display properly the

numbers in case the imaginary part is negative and we

provide an additional constructor to initialise a complex

number to a given value.

... Complex number1; number1 = new Complex(3,5); ... System.out.println("Number 1 = " + number1.getReal() + ((number1.getImaginary()>0)?"+":"") + number1.getImaginary()+"i");

public class Complex{ ... public Complex(int r, int i){ real = r; img = i; } ...

} Overloaded constructor to set

values too

Page 86: Javanotes

The toString() Method

It is recommended that

all subclasses override

this method.

So for our Complex

number class the

toString() method would

look aside.

This method is the

method called when you

try to print the object

directly.

public class Complex{ ... // Overiding the default toString public String toString(){ return(real+((img>0)?"+":"")+img+"i"); } ...

} ... Complex number1; number1 = new Complex(3,5); ... System.out.println("Number 1 = "+number1);

The toString() returns a string representation of the object.

In general, the toString() method returns a string that "textually represents" this

object. The result should be a concise but informative representation that is easy

for a person to read.

Solution is now much more

elegant than previous slide

Page 87: Javanotes

Text Formatting

The formatter class is used to present a formatted output.

Instead of using the Formatter class on its own it is much more

convenient to use it a a method in the Printstream (System.out)

or in the String classes.

is equivalent to:

System.out.printf("%6d", 498);

Formatter fmt = new Formatter(System.out);

fmt.format("%6d", 498);

int n1=34, n2=9; int n3=n1+n2;

System.out.printf("%3d + %3d = %5d", n1 , n2 , n3);

Page 88: Javanotes

Formatting Options

When the string

needs to be

formatted without

displaying it, the

String class provides

a static method

format which is

similar to the above.

Flags: The optional

flags is a set of

characters that

modify the output

format.

Integers: % <field width> d

Real Numbers : % <field width> . <decimal places> f

Strings: % s

Hex: %x or %X

Octal: %o

Character %c

Scientific %e or %E

„-‟: left justified „+‟: always include a sign

„(„: negative number in brackets

A better toString for Complex public String toString(){ return(String.format("%d %+di",real,img));

}

These are just some of the

control strings possible in the

printf

always show

sign

Page 89: Javanotes

Returning Objects

As we can return a primitive data value from a method, we can return an

object from a method too.

We return an object from a method, we are actually returning a reference

(or an address) of an object.

This means we are not returning a copy of an object, but only the reference

of this object public class Roots { public static void main (String args[]){ Complex n1 = new Complex(5,-5); Complex n2 = new Complex(2,-3); Complex n3 = n1.add(n2); System.out.println("Number 1 = "+n1); System.out.println("Number 2 = "+n2); System.out.printf("(%s) + (%s) = %s",n1,n2,n3); }

}

in main

class

result is

assigned to n3

Page 90: Javanotes

Implementation of add in Complex

public Complex add(Complex num){ Complex result = new Complex(); result.real = num.real+this.real; result.img = num.img+this.img; return result;

}

}

public Complex add( Complex num){

result

this = +

return result

n3

returns a pointer to a class

Complex

method in class

Complex

Page 91: Javanotes

Here we first consider the selection constructs in java,

namely the if and the switch statements, followed by the

three iterative constructs, namely, the for loop, while loop

and the do while loop.

We also investigate the alternative recursive procedure

to obtain the same things in a more elegant, sometimes

more inefficient way.

Program Control Structures

Page 92: Javanotes

The Student

Class

public class Student { private String name; private int mark; public Student(){ name = ""; mark = 0; } public Student(String n, int m){ name = n; mark = m; } public void setName(String n){ name = n; } public void setMark(int m){ mark = m; } public String getName(){ return name; } public int getMark(){ return mark; } public boolean equals(Student s){ return this.getName().equals(s.getName()); } public int compareTo(Student s){ return this.name.compareTo(s.getName()); } public String toString(){ return "Name: "+name+" Mark: "+mark; }

}

This example will be used throughout the rest of the

chapters so pay attention

mark

name

member methods

Student

Note: This is overloading

not overriding!

:Student

-name: String

-mark: int

+Student() +Student(String,int) +setName(String); +setMark(int) +getMark():int +getName():String +equals(Student):boolean +compareTo(String):int

+toString():String

Page 93: Javanotes

Selection Statements

The first selection statement is the if statement.

The else part is optional in this statement

Page 94: Javanotes

The if Statement

In this syntax, if the boolean expression evaluates to true, the

following statement or block of statements enclosed within

braces is performed, otherwise nothing is executed.

if ( <boolean expression> ) <statement>;

if ( mark < 45 )

System.out.println(“You failed”);

no “then” keyword, we use brackets

instead

Page 95: Javanotes

use semicolon before else if no

braces are used

The if-else statement

Here, if the boolean expression evaluates to true, the

statement1 or block of statements enclosed within braces is

performed, otherwise Statement2 is performed.

if ( <boolean expression> ) <statement 1>; else <statement 2>;

if ( mark < 45 ) System.out.println(“You failed”); else { System.out.println(“Lucky !! “); mark++;

}

use braces to enclose

more than one statement

No semicolon here!

Page 96: Javanotes

Boolean Operators && || !

Use boolean operators to join expressions

&& is the logical and operator

|| is the logical or operator

! is the not operator

P Q P && Q P || Q !P

false false false false true

false true false true true

true false false true false

true true true true false

if ( wage > 45000 && holiday == true && !married ) System.out.println(“You can go on holiday to Hawaii”); else { System.out.println(“Go work!!“);

}

Page 97: Javanotes

Nested if‘s

The else associates

with the nearest if.

Thus braces must be

used to impose the

required association.

Use of nested if‘s

can be a bit

confusing at times

and it is sometimes

preferred to use the

switch statement.

Page 98: Javanotes

Comparing Objects

With primitive data types, we have only one way to compare

them, but with objects (reference data type), we have two

ways to compare them

We can test whether two variables point to the same object (use ==), or

We can test whether two distinct objects have the same contents.

Proper way to compare the contents‖

String str1 = new String("Java"); String str2 = new String("Java"); if (str1.equals(str2)) { System.out.println("They are equal"); } else { System.out.println("They are not equal"); }

same sequence of

characters

Page 99: Javanotes

Comparing Objects with ==

String str1 = new String("Java"); String str2 = new String("Java"); if (str1 == str2) { System.out.println("They are equal"); } else { System.out.println("They are not equal");

}

String str1 = new String("Java"); String str2 = str1; if (str1 == str2) { System.out.println("They are equal"); } else { System.out.println("They are not equal");

}

J a v a

str1

str2

str1 J a v a

str2 J a v a

Page 100: Javanotes

equals Implementation in Complex

public class Roots{

public static void main (String args[]){

Complex number1 = new Complex(2,-5);

Complex number2 = new Complex(2,-5);

System.out.println("Number 1 = "+number1);

System.out.println("Number 2 = "+number2);

if(number1.equals(number2))

System.out.println("They are equal");

}

}

public boolean equals(Complex other){ return ((this.real==other.real) && this.img==other.img));

}

method in class

Complex

in main

class

if ((this.real==other.real)&&(this.img==other.img)) return true; else

return false;

useless

code

We will see a better

implementation

later

Page 101: Javanotes

The switch Statement

The switch statement avoids a lot of nested if‘s

Note:

Only integral constants may be tested

If no condition matches, the default is executed

If no default, nothing is done (not an error). There can be

only one default

The break is a must! otherwise all statements from the

matched case onwards are executed

Page 102: Javanotes

Syntax of the switch Statement

Page 103: Javanotes

Example of the switch Statement

System.out.print("Input number of legs: "); int legs = keyboard.nextInt(); switch(legs){ case 0: System.out.println("There's something fishy!"); break; case 1: case 3: case 5: System.out.println("That's odd!"); break; case 6: System.out.println("There must be a bug!"); System.out.println("Get it debugged"); break; default:System.out.println("It's a sort of creature");

}

float f switch (f) { case

2:

switch (i) {

case 2*j:

Page 104: Javanotes

Iterations (Repetitive Statements)

Repetition statements control a block of code to be executed

for a fixed number of times or until a certain condition is met.

Count-controlled repetitions terminate the execution of the

block after it is executed for a fixed number of times.

Sentinel-controlled repetitions terminate the execution of the

block after one of the designated values called a sentinel is

encountered.

Repetition statements are also called loop statements.

Page 105: Javanotes

The while statement (A Pretested Loop)

int sum = 0, number = 1; while ( number <= 100 ) { sum += number; number++;

}

while ( number <= 100 );

{

Page 106: Javanotes

The do-while Statement (Post-tested)

Use this when you want to loop at least once.

Ideal for keyboard entry validation.

int sum = 0, number = 1; do { sum += number; number++;

} while ( sum <= 1000000 );

Page 107: Javanotes

for loops (Another Pretested loop)

Page 108: Javanotes

for Loops Examples

for (int j = 2; j < 40; j *= 2) for (int c = 1; c <=3, c++){ for (int r= 1, r <=3, r++){ int product = r * c; System.out.print (“ “ + product); } //finished one row; move on to next row System.out.println(“”);

}

for(int i=0; i < 3 ; i++)

int count =2;

actually a declaration and an assignment. so use

braces or separate

Page 109: Javanotes

Watch out!

Watch out for the off-by-one error (OBOE).

Make sure the loop body contains a statement that will

eventually cause the loop to terminate.

Make sure the loop repeats exactly the correct number of

times.

If you want to execute the loop body N times, then initialize the

counter to 0 and use the test condition counter < N or initialize

the counter to 1 and use the test condition counter <= N.

Avoid a semicolon after the boolean expression cause it will

make it an empty loop.

Page 110: Javanotes

Escape the Block !

‗break‘ takes you out of the present block, and ‗continue‘ will take you at the end

of the end of the body of the loop ie at the next iteration of the body.

You can also escape from a whole nested blocks by using the ‗goto label‘.

All these are interruptions to the normal sequence of operations and should be

very rarely used where the application strictly requires it like the switch statement.

Abuse of these leads to ―spaghetti programming‖

Page 111: Javanotes

Recursive Algorithms

A recursive method is a method that contains a statement (or

statements) that makes a call to itself.

Example - Factorial

The factorial of N is the product of the first N positive integers:

N! = N * (N – 1) * (N – 2 ) * . . . * 2 * 1

for example 5! = 5 * 4 * 3 * 2 * 1

The factorial of N can be defined recursively as

1 if n =1 factorial (n) =

n * factorial (n-1) otherwise

Page 112: Javanotes

Factorial Recursive Implementation

Implementing the factorial of N recursively will result in the

following method.

public static long factorial (long m){ if (m == 1) return 1; else return m* factorial(m-1);

} public static long fac(long m ){ return (m==1)? 1 : m*fac(m-1);

}

long k = factorial(4);

in calling program

shorthand

Page 113: Javanotes

Power Recursive Implementation

Similarly x to the power of y: xy = x * x(y-1)

x if y =1 power(x,y) =

x* power(x,(y-1)) otherwise

public static int power (int x, int y){ if (y == 1) return x; else return ( x* power(x, y-1));

}

int k = power(2,10);

in main

Page 114: Javanotes

Fibonacci series WHEN NOT TO USE RECURSION

The well known series of Fibonacci goes: 1, 1, 2, 3, 5, 8, 13,

etc ..

Where except for the first two terms, each term is the sum of

the previous two terms. The first two terms are 1.

1 n <= 2 fibonacci(n) =

fibonaccci(n-1)+fibonacci(n-2) otherwise

public static long fibonacci (long n){ if (n <=2) return 1; else return (fibonacci(n-1)+fibonacci(n-2));

}

long k = fibonacci(5);

in main

most of the terms are

recalculated

Page 115: Javanotes

One of the most important structures in computer science

are arrays which are variables which can hold a number

of values. These are indispensable for making variables

change in loops and for not using too much variable

names.

Other important structure in Java is the String which is a

series (an array) of characters and Patterns which are

regular expressions used for matching strings and are

much helpful in the validation of input data.

Arrays Strings and Patterns

Page 116: Javanotes

Introduction to Arrays

Array, what is it? An array is a group of variables of the same

data type and referred to by a common name.

An array is contiguous block of memory locations referred by

a common name.

For example to store the marks of 5000 students, you can

declare an array, marks, of size 5000 and can store the marks

of as many students.

int marks[] = new int[5000];

Page 117: Javanotes

Why are Arrays Needed?

You might come across a situation where you need to store

similar type of values for a large number of data items. For

example to store the marks of all the students of a university,

you need to declare thousands of variables.

In addition, each variable name needs to be unique. To avoid

such situations, you can use arrays.

An array consists of a name and the number of elements of the

array. You can refer to a specific array element by the array

name and the element number, which is known as the index.

Note: - Array index element number always starts with 0(zero)

in Java and ends at one less its length.

Page 118: Javanotes

Creating Arrays

The length of an array is fixed at the time of its creation. An

array represents related entities having the same data type in

contiguous or adjacent memory locations. The related data

having data items form a group and are referred to by the

same name.

String employee = new String[5];

Here, the employee is the name of the array and of size 5. The

complete set of values is known as an array and the individual

entities are called as elements of the array.

A specific value in an array is accessed by placing the index

value of the desired element in a square bracket.

String bestEmployee = employee[3];

Page 119: Javanotes

Arrays of Primitive Data Types

Array declaration

<data type> [] <variable name>; or

<data type> <Variable name>[];

Array Creation

<variable> = new <data type> [<size>];

float [] marks; float marks [];

marks = new float[12];

arrays are

objects

Page 120: Javanotes

Array Initialization

Like other data types, it is possible to declare and initialize an

array at the same time.

Page 121: Javanotes

Accessing Individual Elements

To access an individual element of an array we use the

following notation:

<variable name> [<index>]

The size of an array is given by a public data member inside

the array class named length;

marks[2] = 97; m1 = marks [1];

public static void main (String args[]){

Scanner keyboard = new Scanner(System.in);

int assessments[] = new int[3];

//get marks

for(int i=0;i<assessments.length; i++){

System.out.print("Enter mark: ");

assessments[i] = keyboard.nextInt();

}

cast number

not result

//calculate total

int total = 0;

for(int i=0;i<assessments.length;i++){

total += assessments[i];

}

float average = (float)total/3;

System.out.println("The average mark is: "+average);

} (float)(total/3);

Page 122: Javanotes

Variable-Size Declaration

In Java, we are not limited to fixed-size array declaration at

compilation time unlike some other languages.

The following declares an array of size chosen at runtime by

the user:

public static void main (String args[]){

Scanner keyboard = new Scanner(System.in);

int dimension;

System.out.print("Enter dimension of array: ");

dimension = keyboard.nextInt();

float myArray [] = new float [dimension];

} size declared

at runtime

Page 123: Javanotes

Two-Dimensional Arrays

Two-dimensional arrays are useful in representing tabular

information.

Declaration:

<data type> [][] <variable name> or <data type> <variable name> [][];

Creation:

<variable name> = new <data type> [<size>][<size>];

All together:

int [ ][ ] coefs [ ][ ]; int coefs [ ][ ];

coefr = new int[3][5];

effectively a 2D array

is an array of arrays coefs[4][1]=5;

int x = coefs[3][2]=5;

Access elements

Page 124: Javanotes

Matrix (Array) Multiplication

Page 125: Javanotes

Matrix Multiplication Implementation

public static void main (String args[]){

int a[][] = {{5, 2, 0, 10},{3, 5, 2, 5}, {20, 0, 0, 0}};

double b[][] = {{1.50, 0.20},{2.80, 0.40},{5.00, 1.00}, {2.00, 0.50}};

float c [][] = new float [3][2];

for(int i = 0;i< b[0].length; i++){

for(int j = 0;j <a.length;j++){

c[j][i] = 0.0F;

for(int k = 0;k<a[0].length;k++){

c[j][i] += (float)(a[j][k] * b[k][i]);

}

}

}

for( int i =0; i< c.length;i++){

for(int j = 0; j < c[0].length;j++){

System.out.printf(" %6.2f ",c[i][j]);

}

System.out.println("");

}

}

Page 126: Javanotes

Ragged and Multi-Dimensional

In fact in Java, a two dimensional array is an array of arrays

and so the 2D array is not necessarily rectangular

An array in java is stored row-first.

In fact in Java you can have 3D arrays, 4D arrays to any

dimension you desire. It is hard to visualise but a 3D array is

nothing but an array of 2D arrays, etc.

double[][] tri = new double[4][];

for(int i=0;i<4;i++)

tri[i] = new double[i+1];

double[][] [] threeD = new double[4][4][4];

Page 127: Javanotes

Arrays of Objects

In Java, in addition to arrays of primitive data types, we can

declare arrays of objects.

An array of primitive data is a powerful tool, but an array of

objects is even more powerful.

The use of an array of objects allows us to model the

application more cleanly and logically.

Student [] klassi;

klassi = new Studnet[6];

klassi[0] = new Student();

klassi[1] = new Student();

2

1

3

1 2

3

Page 128: Javanotes

Example of 2D Arrays

import java.util.*; public class BestWorst { public static final int SIZE = 3; public static void main (String args[]){ Student [] klassi = new Student[SIZE]; Scanner kb = new Scanner(System.in); kb.useDelimiter("\n"); for(int i = 0; i<klassi.length; i++){ System.out.print("Enter Name & Surname: "); String name = kb.next(); System.out.print("Enter Mark: "); int mark = kb.nextInt(); klassi[i] = new Student(name,mark); }

int bestpos = 0; // assume first to be the best int worstpos = 0; // assume first to be the worst for(int i = 0; i< klassi.length; i++){ if(klassi[i].getMark()>klassi[bestpos].getMark()) bestpos = i; if(klassi[i].getMark()<klassi[worstpos].getMark()) worstpos = i; } System.out.println(klassi[bestpos]); System.out.println(klassi[worstpos]); }

}

to read space between name

and surname

Uses toString in

Student

kb.useDelimiter("\n");

Page 129: Javanotes

Command-Line Arguments

A Java application can accept any number of arguments from the command line.

This allows the user to specify configuration information when the application is

launched.

When an application is launched, the runtime system passes the command-line

arguments to the application's main method via an array of Strings.

public class HaveMore{

public static void main (String args[]){

if (args.length > 0){

System.out.println("You got some extra stuff: ");

for(int i = 0; i <args.length;i++){

System.out.println(args[i]);

}

}

}

}

Page 130: Javanotes

Strings

A string is a sequence of characters that is treated as a single value.

Instances of the String class are used to represent strings in Java.

In Java a String object is immutable

This means that once a String object is created, it cannot be changed, such

as replacing a character with another character or removing a character

The String methods we have used so far do not change the original string.

They created a new string from the original. For example, substring creates

a new string from a given string.

Single characters can be accessed using the charAt() method

String r = "Top 20";

r.charAt(1)

Page 131: Javanotes

Some Useful methods in String

Note: there are far too many methods in class String. See String documentation for a complete list

Page 132: Javanotes

Different String Creations

Depending on the methods used for creation, Sting pointers

can point either to the same object or different objects:

word1 J a v a

word2 J a v a

J a v a

word1

word2

String word1, word2; word1= new String("Java");

word2= new String("Java");

String word1, word2; word1= "Java";

word2= "Java";

Page 133: Javanotes

StringBuffers

In many string processing applications, we would like to change

the contents of a string. In other words, we want it to be

mutable.

Manipulating the content of a string, such as replacing a

character, appending a string with another string, deleting a

portion of a string, and so on, may be accomplished by using

the StringBuffer class.

word

L a v a

word

J a v a

StringBuffer word= new StringBuffer(“Java");

word.setCharAt(0,'L');

Page 134: Javanotes

Patterns - Regular Expressions

A Pattern is called a regular expression.

Rules

The brackets [ ] represent choices

The asterisk symbol * means zero or more occurrences.

The plus symbol + means one or more occurrences.

The hat symbol ^ means negation.

The hyphen – means ranges.

The parentheses ( ) and the vertical bar | mean a range of choices for

multiple characters.

if(entry.matches("(21|27|79|99)[0-9]{6}"))

System.out.println("Valid Telephone Number ");

else

System.out.println("Invalid Telephone Number");

Page 135: Javanotes

Some Examples

Expression Description

[013] A single digit 0,1 or 3

[0-9][0-9] Any two digit number 00 to 99

[0-9&&[^4567]] A single digit 0,1,2,3,8 or 9

[a-z0-9] Single lower case character or digit

[a-zA-Z][a-zA-Z0-9_$] A valid Java identifier consisting of alphanumeric

characters, underscores and dollar sign, with the first

charcter being an alphabetic character

[wb][qd|eed] Matches wad weed and beed

(AZ|CA|CD)[0-9][0-9] Matches AZxx, CAxx and COxx, where x is a single

digit

Page 136: Javanotes

Garbage Collection

Garbage collection is the process of automatically finding memory

blocks that are no longer being used ("garbage"), and making

them available again. In contrast to manual deallocation that is

used by many languages, eg C and C++, Java automates this

error-prone process and avoids two major problems:

Dangling references. When memory is deallocated, but not all pointers to it

are removed, the pointers are called dangling references -- they point to

memory that is no longer valid and which will be reallocated when there is a

new memory request, but the pointers will be used as tho they still pointed to

the original memory.

Memory leaks. When there is no longer a way to reach an allocated memory

block, but it was never deallocated, this memory will sit there. If this error of

not deleting the block occurs many times, eg, in a loop, the program may

actually crash from running out of memory.

Page 137: Javanotes

Javadoc

Many of the programmer-defined classes we design are intended to be

used by other programmers.

It is, therefore, very important to provide meaningful documentation to the

client programmers so they can understand how to use our classes correctly.

By adding javadoc comments to the classes we design, we can provide a

consistent style of documenting the classes.

Once the javadoc comments are added to a class, we can generate HTML

files for documentation by using the javadoc command.

Javadoc comments begins with /** and ends with */

Special information such as the authors, parameters, return values, and

others are indicated by the @ marker

@param @author @return @version

see: http://java.sun.com/j2se/javadoc

Page 138: Javanotes

Stacks

A programmer‘s stack is a simple concept with wide application. Stacks

can be found in all kinds of programs, at system level and in every

field of application. To maintain the analogy of a physical stack (of

bricks or trays) we draw a programmer‘s stack (of numbers, chars or

even objects) upside down.

A stack may be created, as depicted, from an array of stackable

objects and an integer variable for storing the number of objects

currently stacked (top of stack)

Three functions needed to manage such a stack:

push: Place a new object on the top of the stack

pop: Take the item that is on top of the stack

peep: Take a copy of the item on top of the stack without removing it.

Page 139: Javanotes

Stack Example - Reversing a String

Using the stack, we can easily reverse a string entered from

the keyboard. public class Stack { private int tos; char stack[] = new char[40]; public Stack() { tos = 0; } public void push(char item){ if (tos <40) stack[tos++] = item; }

public static void main (String args[]){

Scanner kb = new Scanner(System.in);

Stack x= new Stack();

System.out.print("Enter a string: ");

String entry = kb.nextLine();

for(int i = 0; i < entry.length(); i++)

x.push(entry.charAt(i));

for(int i = 0; i < entry.length();i++)

System.out.print(x.pop());

}

public char pop(){ char item=' '; if (tos > 0) item = stack[--tos]; return item; } public char peep(){ char item=' '; if (tos >= 0) item = stack[tos]; return item; }

}

Page 140: Javanotes

Reverse Polish Notation

Algebraic expressions in conventional form may be expressed in reverse

Polish notation which was devised by the polish logician Jan Lukaciewicz,

which only Poles can pronounce. ‗Reverse because his original order of

operators and operands has been reversed.

As an example of reverse Polish notation:

The reverse Polish expression is easier to evaluate than might appear.

For example let A=6, B=4, C=1, D = 2, F=3, G =7 and H = 5.

With these values the expression to be evaluated is:

Work from left to right taking each item in turn. Whenever you come to an operator,

apply it to the previous two terms, reducing two terms to one:

Page 141: Javanotes

Implementation of the RPN Stack

The reverse Polish notation would be useful for

evaluating expressions by computer. So how do

you transform an expression such as the one

above:

In addition to the three functions of the stack we

need another function which returns the

precedence of an operator.

This static class should be included in the main

(ReversePolish) class to Calculate the precedence

among operators.

Notice that the left bracket is included in the

precedence table and allocated low

precedence. This is a trick to avoid treating

explicitly the condition ... or is a left bracket ...

private static int prec( char ch){ switch(ch){ case '=': return 0; case '(': return 1; case '+': case '-': return 2; case '*': case '/': return 3; default : return -1; }

}

Page 142: Javanotes

RPN Algorithm

Page 143: Javanotes

Implementation of the RPN

import java.util.Scanner; public class ReversePolish{ public static void main (String args[]){ Stack x = new Stack(); Stack y = new Stack(); Scanner kb = new Scanner(System.in); System.out.print("Input: "); String equation = kb.nextLine(); int pos = 0; char token; do{ token = equation.charAt(pos++); switch(token){ case '(': y.push(token); break; case ')': while (y.peep() !='('){ x.push(y.pop()); } y.pop(); break;

case '+': case '-': case '*': case '/': case '=': while((y.peep()!=' ') && (prec(token) <= prec(y.peep()))) x.push(y.pop()); y.push(token); break; default: if ((""+token).matches("[A-Za-z]")) x.push(token); } }while(token != '='); for(int i=0; i<equation.length();i++) y.push(x.pop()); System.out.print("Output: "); for(int i=0; i<equation.length();i++) System.out.print(y.pop()); }

}

Page 144: Javanotes

In this chapter we investigate in detail what is meant by

inheritance and the other important principle of

polymorphism.

A property of object oriented programming like

overloading and overriding is also shown here in detail.

Cloning of objects is discussed together with how objects

can be compared between them for sorting etc.

Inheritance & Polymorphism

Page 145: Javanotes

Case Study

Suppose we want to implement a model of class Student that contains both

first year and second year students at the Junior College.

Each student‘s record will contain his or her name, the assessment mark,

and the final exam grade for first years and the assessment mark and

project mark for second years.

The formula for determining if the student passed the year is different for

first and second year students.

There are two ways to design the classes to model first and second year

students.

We can define two unrelated classes, one for first and one for second years.

We can model the two kinds of students by using classes that are related in an inheritance

hierarchy.

Two classes are unrelated if they are not connected in an inheritance relationship

Page 146: Javanotes

Student Class Hierarchy

For the Class Student example,

we design three classes:

Student

FirstYear

SecondYear

The Student class will incorporate

behavior and data common to

both FirstYear and SecondYear

objects.

The FirstYear class and the

SecondYear class will each

contain behaviours and data

specific to their respective

objects.

Class FirstYear extends Student {

:FirstYear:

-exam

+setExam(int)

+getExam():int

inheritance

hierarchy

-project

+setProject(int)

+getProject():int

:SecondYear:

:Student

#name

#mark

+Srudent() +Student(String,int) +setName(String); +setMark(int) +getMark():int

+getName():String

Protected

data

public

data

Page 147: Javanotes

Access Modifiers

Access modifiers can be of four types:

private: data members and methods are accessible only to the member

methods of that same class .In UML class diagrams it is denoted by the

minus sign ( -).

protected: data members and methods are accessible to member

methods of that same class and all the in methods in the inherited

subclasses. In diagrams it is denoted by the hash sign (#).

package friendly: data members and methods are accessible by member

methods of all the classes in the same package. When an access

modifier is not specified this is the default access modifier.

public: data members and methods are accessible by all methods. In

diagrams it is denoted by the plus sign(+).

Page 148: Javanotes

Visibility

:Super

:Sub Super

Sub

Inheritance

hierarchy

Instances accessible

inaccessible

:Client :Sub

:Super

:Super

:Sub

one:Class1 two:Class1

accessibility from

another instance

accessibility from sub to

super

Page 149: Javanotes

Inheritance and Constructors

Unlike members of a superclass, constructors of a superclass

are not inherited by its subclasses.

You must define a constructor for a class or use the default

constructor added by the compiler.

If the class declaration does not explicitly designate the

superclass with the extends clause, then the class‘s superclass is

the Object class. super is also used to call an overridden

method of a superclass .

super();

calls the superclass‟s constructor.

super.getPassed();

Page 150: Javanotes

Method Overriding

Overriding is to provide a replacement method in a new class for

one in the superclass.

The superclass too will use your new method in place of its own when

dealing with objects of the subclass type, though it will continue to

use its own method for objects purely of its own type.

In the next example, if you try to print an object of type Student, the

toString method defined in the superclass Student will be used,

otherwise one from the appropriate subclasses will be used on

FirstYear and SecondYear.

We say that the method in either FirstYear or SecondYear has

overridden that in student, which in turn has overridden that defined

in Object.

Page 151: Javanotes

Subclasses Implementation

public final class FirstYear extends Student{ private int exam; public FirstYear(String n, int m, int e){ super(n,m); exam = e; } public void setExam(int e){ exam = e; } public int getExam(){ return exam; } public final boolean hasPassed(){ return(mark+exam)> 45; } public String toString(){ return(super.toString()+" Exam: "+exam); }

}

public final class SecondYear extends Student{ private int project; public SecondYear(String n, int m, int p){ super(n,m); project = p; } public void setProject(int p){ project = p; } public int getProject(){ return project; } public final boolean hasPassed(){ return(mark+project)> 45; } public String toString(){ return(super.toString()+" Project: "+project); }

}

FIRSTYEAR

CLASS SECONDYEAR

CLASS

Page 152: Javanotes

Polymorphism

Polymorphism allows a single variable to refer to objects from

different subclasses in the same inheritance hierarchy

For example, if Cat and Dog are subclasses of Pet, then the

following statements are valid:

Creating the college array

We can maintain our class College using an array, combining objects

from the Student, FirstYear, and SecondYear classes.

From the example below we can see that java has selected the

appropriate toString method. It chose that of FirstYear for the first case

and that of SecondYear for the second case. This is called dynamic

method dispatch

Pet fido = new Dog();

Pet felix = new Cat();

Page 153: Javanotes

Referencing

A reference to a superclass can be used to reference any of its

subclass.

public class Kulegg{

public static void main(String args[]){

Student[] college = new Student[6];

college[0] = new FirstYear("John Cutajar",20,70);

college[1] = new SecondYear("Maria Cutajar",30,60);

System.out.println(college[0]);

System.out.println(college[1]);

}

}

Student s = new FirstYear();

Page 154: Javanotes

Abstract Classes and Methods

When we define a superclass, we often do not need to create

any instances of the superclass. In this case we must define the

class differently as an abstract class.

Definitions

An abstract class is a class

defined with the modifier abstract OR

that contains an abstract method OR

that does not provide an implementation of an inherited abstract method

An abstract method is a method with the keyword abstract, and it ends

with a semicolon instead of a method body. Private methods and static

methods may not be declared abstract, and no instances can be created

from an abstract class.

Page 155: Javanotes

Considerations

Case 1: Student Must Be FirstYear or SecondYear

If a student must be either a FirstYear or a SecondYear student, we only

need instances of FirstYear or SecondYear.

Therefore, we must define the Student class so that no instances may be

created of it.

Case 2: Student Does Not Have to be FirstYear or SecondYear.

In this case, we may design the Student class in one of two ways.

We can make the Student class instantiable.

We can leave the Student class abstract and add a third subclass,

OtherStudent, to handle a student who does not fall into the FirstYear or

SecondYear categories.

Which Approach to Use : depends on the particular situation.

Page 156: Javanotes

The Java Interface

A Java interface includes only constants and abstract methods.

An abstract method has only the method header, or prototype.

There is no method body.

You cannot create an instance of a Java interface.

A Java interface specifies a behavior.

A class implements an interface by providing the method body

to the abstract methods stated in the interface.

Any class can implement the interface.

Page 157: Javanotes

Inheritance versus Interface

The Java interface is used to share common behaviour (only

method headers) among the instances of different classes.

Inheritance is used to share common code (including both data

members and methods) among the instances of related classes.

In your program designs, remember to use the Java interface

to share common behaviour. Use inheritance to share common

code.

If an entity A is a specialized form of another entity B, then

model them by using inheritance. Declare A as a subclass of B.

Page 158: Javanotes

Inheritance of an Abstract Class

If a class inherits an abstract class it must either provide an implementation

for abstract method, or declare that method again as abstract.

This is useful to force the programmer to provide a method which cannot be

implemented at the time of definition of the superclass.

At the time of implementation of the Student class we cannot decide if a

student has passed or not since we need either the project or exam mark.

We can force though the descendants to implement such method by

declaring it.

public abstract class Student {

...

college[2] = new Student("Joe Cutajar",20);

public abstract boolean hasPassed();

Page 159: Javanotes

The Object Class

Class Object is the root of the class hierarchy. Every class has

Object as a superclass. All objects, including arrays, implement

the methods of this class.

Since a pointer to a superclass can point to any subclass, a

pointer to object can practically point to anything since all

classes are subclasses of object.

Some interesting methods inherited from object are:

Object clone(): Creates and returns a copy of this object.

boolean equals(Object obj) : Indicates whether some other object is

"equal to" this one.

String toString(): Returns a string representation of the object. In the

case of an object the classname followed by @ and the hash address

Page 160: Javanotes

Cloning

Objects in Java are referred using reference types, and there is no direct

way to copy the contents of an object into a new object.

The assignment of one reference to another merely creates another

reference to the same object. Therefore, a special clone() method exists for

all reference types in order to provide a standard mechanism for an object

to make a copy of itself.

Why create a local copy?

The most probable reason for creating a local copy of an object is because you

plan to modify the object, and you don't want to modify the method caller's

object. If you decide that you need a local copy, you can perform the operation

by using the clone() method of the Object class. The clone() method is defined as

protected, but you must redefine it as public in all subclasses that you might want

to clone.

Page 161: Javanotes

Shallow Copy

The clone() method produces an Object, which must be

recast to the proper type.

The example shows how ArrayList's clone() method

does not automatically try to clone each of the objects

that the ArrayList contains -- the old ArrayList and the

cloned ArrayList are aliased to the same objects.

This is often called a shallow copy, since it's only

copying the "surface" portion of an object.

The actual object consists of this "surface," plus all the

objects that the references are pointing to and all the

objects those objects are pointing to, etc.

This is often referred to as the "Web of objects―.

When you copy the entire mess, it is called a deep

copy.

clonin

g

Page 162: Javanotes

Cloning Example

public class FirstYear extends Student implements Cloneable{ private int exam; public FirstYear(String n, int m,int e){ super(n,m); exam = e; } .... public String toString(){ return(super.toString()+" Exam: "+exam); } public Object clone(){ try{ return super.clone(); } catch (CloneNotSupportedException e){ return null; } }

}

import java.util.*; public class Cloning{ public static void main( String args[]){ FirstYear john = new FirstYear("John Cutajar",24,50); FirstYear ivan = (FirstYear)john.clone(); FirstYear alias = john; john.setName("Gianni"); System.out.println(john+",\n"+alias+" &\n"+ivan); }

}

Page 163: Javanotes

The Comparable Interface

This are used for comparing objects in Java. Using these

concepts; Java objects can be sorted according to a

predefined order.

A comparable object is capable of comparing itself with

another object.

The class itself must implements the java.lang.Comparable

interface in order to be able to compare its instances.

This interface requires the particular class which implement it to

provide the implementation of the method compareTo() in

order to be able to compare any two objects of that type.

Page 164: Javanotes

Comparable Example

import java.util.*; public class Student implements Comparable <Student>{ ... public int compareTo(Student s){ return this.name.compareTo(s.getName()); } ...

} import java.util.*; public class UseSort{ public static void main (String args[]){ ArrayList <Student> c1a3 = new ArrayList<Student> (); c1a3.add(new Student("Pinu Cutajar",78)); c1a3.add(new Student("John Cutajar",98)); c1a3.add(new Student("Maria Cutajar",76)); System.out.println("Unsorted List:"+c1a3); Collections.sort(c1a3); System.out.println("Sorted List:"+c1a3); }

}

Page 165: Javanotes

The Comparator Class

A comparator object is capable of comparing two different objects.

The class is not comparing its instances, but some other class‘s instances.

This comparator class must implement the java.lang.Comparator interface

and this involves implementing the compare method.

In the previous example, If we need to sort using other fields (say mark) of

the student, we‘ll have to change the Student class‘s compareTo() method to

use those fields. But then we‘ll loose this named based sorting mechanism.

This is not a good alternative if we need to sort using different fields at

different occasions. But no need to worry; Comparator is there to save us.

By writing a class that implements the java.lang.Comparator interface, you

can sort Students using any field as you wish even without touching the

Student class itself; Student class does not need to implement

java.lang.Comparable or java.lang.Comparator interface.

Page 166: Javanotes

Comparator Example

import java.util.*; public class ListDescending implements Comparator <Student>{ public int compare(Student s1, Student s2){ return (s2.getMark()-s1.getMark()); }

}

import java.util.*; public class UseSort{ public static void main (String args[]){ ArrayList <Student> c1a3 = new ArrayList<Student> (); c1a3.add(new Student("Pinu Cutajar",78)); c1a3.add(new Student("John Cutajar",98)); c1a3.add(new Student("Maria Cutajar",76)); System.out.println("Unsorted List:"+c1a3); Collections.sort(c1a3,new ListAscending()); System.out.println("Sorted Ascending:"+c1a3); Collections.sort(c1a3,new ListDescending()); System.out.println("Sorted Descending:"+c1a3); }

}

import java.util.*; public class ListAscending implements Comparator <Student>{ public int compare(Student s1, Student s2){ return (s1.getMark()-s2.getMark()); }

}

Page 167: Javanotes

In this chapter we investigate the various data structures

available.

Many of these are implemented from first principles in

java, although java encapsulates much of these in

already made classes which are much easier to use.

The most important structures for storing data are lists

and trees and all incorporated in java Collections.

Data Structure

Page 168: Javanotes

Abstract Data Types

An Abstract Data Type (ADT) is more a way of looking at a

data structure: focusing on what it does and ignoring how it

does its job.

A stack or a queue is an example of an ADT.

It is important to understand that both stacks and queues can

be implemented using an array. It is also possible to implement

stacks and queues using a linked list.

This demonstrates the "abstract" nature of stacks and queues:

how they can be considered separately from their

implementation.

To best describe the term Abstract Data Type, it is best to

break the term down into "data type" and then "abstract".

Page 169: Javanotes

Abstract

Lets look at the "abstract" portion of the phrase. The word abstract in

our context stands for "considered apart from the detailed

specifications or implementation".

In Java, an Abstract Data Type is a class considered without regard to

its implementation.

It can be thought of as a "description" of the data in the class and a

list of operations that can be carried out on that data and instructions

on how to use these operations.

What is excluded though, is the details of how the methods carry out

their tasks.

An end user (or class user), should be told is what methods to call, how

to call them, and the results that should be expected, but not HOW

they work.

Page 170: Javanotes

Data Type

In Java, any class represents a data type, in the sense that a

class is made up of data (fields) and permissible operations on

that data (methods).

By extension, when a data storage structure like a stack or

queue is represented by a class, it too can be referred to as a

data type.

A stack is different in many ways from an int, but they are both

defined as a certain arrangement of data and a set of

operations on that data.

Page 171: Javanotes

Linked Lists

The implementation of the stack as seen in chapter 5 had a

limitation of size since the size was declared beforehand

during the implementation of the program.

Dynamic memory allocation is used when the size is decided at

run-time. or when we want a particular to be extendible during

execution.

Here we are going to implement a simple linked list made of

nodes, each pointing to the next

Page 172: Javanotes

Insertion and Deletion

Insertion deletion

Page 173: Javanotes

Example public class Klassi{ private StudentNode start; public Klassi(){ start = null; } public void add(Student s){ StudentNode scan = start; StudentNode sn = new StudentNode(s); if(scan==null) start=sn; else{ while(scan.getNext()!=null) scan = scan.getNext(); scan.setNext(sn); } } public String toString(){ String list = ""; StudentNode scan = start; while(scan != null){ list += ("\n"+scan); scan = scan.getNext(); } return(list); }

}

public class StudentNode extends Student{ private StudentNode next; public StudentNode(Student s){ super(s.name, s.mark); next = null; } public void setNext(StudentNode s){ next = s; } public StudentNode getNext(){ return next; }

}

Page 174: Javanotes

The main import java.util.Scanner; public class UseList{ public static final int SIZE = 3; public static void main (String args[]){ Scanner kb = new Scanner(System.in); kb.useDelimiter("\n"); Klassi c1a3 = new Klassi(); for(int i = 0; i < SIZE; i ++){ System.out.print("Enter name & surname: "); String name = kb.next(); System.out.print("Enter mark: "); int mark = kb.nextInt(); Student s = new Student(name,mark); c1a3.add(s); } System.out.println(c1a3); }

}

Page 175: Javanotes

Doubly Linked Rings

The fundamental record of a doubly linked ring has a pointer

to the previous and next node.

Access to records in a ring is simplified by employing one

record as dummy head as illustrated below.

This device makes it unnecessary to check whether the record

to be added or deleted is next to a fixed head, and if so take

special action (Very messy).

Page 176: Javanotes

Inserting and Deleting

InsertiNG YOUNG BEFORE OLD

Deleting old

Page 177: Javanotes

Example – UseRing & Ring Classes

public class RingNode extends Student{ private RingNode prev; private RingNode next; public RingNode(Student s){ super(s.name,s.mark); prev = null; next = null; } public void setPrev(RingNode p){ prev = p; } public RingNode getPrev(){ return prev; } public void setNext(RingNode n){ next = n; } public RingNode getNext(){ return next; }

}

import java.util.Scanner; public class UseRing{ public static final int SIZE = 3; public static void main (String args[]){ Scanner kb = new Scanner(System.in); kb.useDelimiter("\n"); Directory attendance = new Directory(); for(int i = 0; i < SIZE; i ++){ System.out.print("Enter name & surname: "); String name = kb.next(); System.out.print("Enter mark: "); int mark = kb.nextInt(); Student s = new Student(name,mark); attendance.add(s); } System.out.println(attendance); System.out.print("\nEnter student to delete: "); String name = kb.next(); attendance.delete(new Student(name,0)); System.out.println(attendance); }

}

Page 178: Javanotes

Example - Directory Class

public void add(Student s){ RingNode old = getBefore(s); RingNode young = new RingNode(s); young.setNext(old); young.setPrev(old.getPrev()); old.getPrev().setNext(young); old.setPrev(young); } public void delete(Student s){ RingNode old = find(s); old.getNext().setPrev(old.getPrev()); old.getPrev().setNext(old.getNext()); } public String toString(){ RingNode scan = start.getNext(); String list =""; while (scan != start){ list += "\n"+scan; scan = scan.getNext(); } return list; }

}

public class Directory{ private RingNode start; public Directory(){ start = new RingNode(new Student()); start.setPrev(start); start.setNext(start); } public RingNode getBefore(Student s){ RingNode scan = start.getNext(); while(scan != start && scan.compareTo(s) < 0) scan = scan.getNext(); return scan; } public RingNode find(Student s){ RingNode scan = start.getNext(); while(scan != start && !scan.equals(s)) scan = scan.getNext(); return scan; }

Page 179: Javanotes

Binary Search Trees

Take some letters to insert:

D, Z, B, E, A, F, C

Bring the first letter, D, to the root of the tree and

store it as a node (Trees grow upside down as do

several metaphors in computing)

Now take the next letter, Z, and bring it to to the

root node. It is ‗bigger‘ than D so go right and make

a new node to contain Z as shown.

Now the third letter, B, It is smaller than D so go and

make a new node.

The next letter , E, is bigger than D so go to the

right. It is smaller than Z so go left. Then make a

new node to contain E as shown here.

Page 180: Javanotes

In General Insertion

In general, bring the next letter to the root node and compare.

If the new letter as smaller go left, if bigger go right.

Do the same thing as you reach the next node, and so and so

forth until you eventually find no node for comparison (null). At

that stage make a new and store the new letter in it.

Page 181: Javanotes

Deletion

There are several cases to be considered:

Deleting a leaf: Deleting a node with no children is easy, as we can

simply remove it from the tree.

Deleting a node with one child: Delete it and replace it with its child.

Deleting a node with two children: Call the node to be deleted "N". Do

not delete N. Instead, chose either the oldest of the younger children or

the youngest of the elder children say node, "R". Replace the value of N

with the value of R, then delete R. (Note: R itself have up to one child)

As with all binary trees, a node's in-order successor is the left-

most child of its right subtree, and a node's in-order

predecessor is the right-most child of its left subtree. In either

case, this node will have zero or one children. Delete it

according to one of the two simpler cases above.

Page 182: Javanotes

Implementation

public static String traverse(order p,Node n){ String list = ""; switch(p){ case IN: if (n !=null){ list = traverse(order.IN,n.getLeft()); list += "->"+ n; list += traverse(order.IN,n.getRight()); } break; case PRE: if (n !=null){ list = "->"+ n; list +=traverse(order.PRE, n.getLeft()); list +=traverse(order.PRE, n.getRight()); } break; case POST: if (n !=null){ list = traverse(order.POST,n.getLeft()); list += traverse(order.POST, n.getRight()); list += "->"+ n; } } return list; }

}

public class Tree{ public static enum order {IN, PRE,POST}; public static Node addNode(Node n, char ch){ if (n == null) n = new Node(ch); else if (ch < n.getData()) n.setLeft(addNode(n.getLeft(),ch)); else n.setRight(addNode(n.getRight(),ch)); return n; }

Page 183: Javanotes

Tree Traversals

In in-order traversal the tree is traversed as shown on the right . Notice that the arrow runs through the

letters alphabetically. The nodes of this tree can be depicted

and defined easily:

In pre-order traversal the tree is traversed as shown on the left. First the node, then

the left subtree then the right subtree

In post-order traversal the tree is traversed as shown on the right First the left subtree then the right subtree, then the node

itself,

Page 184: Javanotes

Main and Node Classes public class Node{ private Node left; private Node right; private char data; public Node (char ch){ left = null; right = null; data= ch; } public void setLeft(Node n){ left = n; } public void setRight(Node n){ right = n; } public Node getLeft(){ return left; } public Node getRight(){ return right; } public char getData(){ return data; } public String toString(){ return ""+data; }

}

import java.util.Scanner; public class Garden{ public static void main (String args[]){ Scanner kb = new Scanner(System.in); kb.useDelimiter("\n"); System.out.print("Enter string to shuffle: "); String entry = kb.next(); Node root = null; for(int i = 0; i < entry.length(); i ++) root = Tree.addNode(root,entry.charAt(i)); System.out.println("In Order: "+Tree.traverse(Tree.order.IN,root)); System.out.println("Pre Order: "+Tree.traverse(Tree.order.PRE,root)); System.out.println("Post Order: "+Tree.traverse(Tree.order.POST,root)); }

}

Page 185: Javanotes

JCF Lists

The java.util standard package contains different types of

classes for maintaining a collection of objects.

These classes are collectively referred to as the Java Collection

Framework (JCF). JCF includes classes that maintain collections

of objects as sets, lists, or maps.

JCF Lists

JCF includes the List interface that supports methods to maintain a

collection of objects as a linear list

L = (l0, l1, l2, . . . , lN)

We can add to, remove from, and retrieve objects in a given list.

A list does not have a set limit to the number of objects we can add to it

Page 186: Javanotes

Using Lists

To use a list in a program, we must create an instance of a

class that implements the List interface.

Two classes that implement the List interface:

ArrayList or Vector

LinkedList

The ArrayList class uses an array interface to access data.

The LinkedList class uses a technique called linked-node

representation.

Page 187: Javanotes

ArrayList or Vector

There are various collections in Java

a popular one, very similar to the ArrayList is the Vector.

Here we shall concentrate on ArrayList, although use of Vector is very

similar with method names a bit different.

To use indexOf on ArrayList of Student the equal method must

be added to the student class for proper overriding.

public boolean equals(Object o){ Student s = (Student) o; return s.getName().equals(this.getName());

} override equals not overload it for proper

working of

indexOf()

Page 188: Javanotes

ArrayList Example System.out.println("\nThere are "+c1a3.size() + " elements: \n"+c1a3); System.out.print("\nEnter student to delete:"); name = kb.next(); s = new Student(name,0); if(c1a3.contains(s)){ int pos = c1a3.indexOf(s); Student t = c1a3.get(pos); System.out.print(“Really delete [Y/N]:("+t+"): "); String reply = kb.next(); if (reply.equalsIgnoreCase("Y")) c1a3.remove(pos); } else System.out.println("Student not found"); System.out.println("\nThere are now "+c1a3.size() + " elements \n"+c1a3); }

}

import java.util.*; public class UseArrayList{ public static void main (String args[]){ Scanner kb = new Scanner(System.in); kb.useDelimiter("\n"); ArrayList <Student> c1a3 = new ArrayList <Student> (); Student s; String name; do{ System.out.print("Enter name & surname: "); name = kb.next(); if (!name.equals("end")){ System.out.print("Enter mark: "); int mark = kb.nextInt(); s = new Student(name,mark); c1a3.add(s); } }while (!name.equals("end"));

Page 189: Javanotes

JCF Maps

JCF includes the Map interface that supports methods to

maintain a collection of objects (key, value) pairs called map

entries.

To use a map in a program, we must create an instance of a

class that implements the Map interface.

Two classes that implement the Map interface:

HashMap

TreeMap

key value

k0 v0 k1 v1 . -

kn vn

key-value pair

Page 190: Javanotes

Iterators

Iterators let you process each element of a Collection. Iterators

are a nice generic way to go through all the elements of a

Collection no matter how it is organised. Iterator is an Interface

implemented a different way for every Collection.

import java.util.*; public class UseIterator{ public static void main (String args[]){ ArrayList <Student> c1a3 = new ArrayList <Student>(); c1a3.add(new Student("John",45)); c1a3.add(new Student("Maria",65)); c1a3.add(new Student("Manuel",85)); Iterator p = c1a3.iterator(); while (p.hasNext()) System.out.println(p.next()); }

}

Page 191: Javanotes

for-each loop

The basic for loop was extended in Java 5 to make iteration

over arrays and other collections more convenient.

This newer for statement is called the enhanced for or for-

each.

This is a very useful method to scan each element in a

collection.

for(Student s: c1a3)

System.out.println(s);

Page 192: Javanotes

Example - Using TreeMaps import java.util.*; public class UseTrees{ public static void main (String args[]){ Scanner kb = new Scanner(System.in); kb.useDelimiter("\n"); Map <String,Student> c1a3 = new TreeMap <String,Student>(); Student s; String name,id; do{ System.out.print("Enter name & surname or \“end\”: "); name = kb.next(); if (!name.equals("end")){ System.out.print("ID Card Number: "); id = kb.next(); System.out.print("Enter mark: "); int mark = kb.nextInt(); s = new Student(name,mark); c1a3.put(id,s); } }while (!name.equals("end"));

System.out.println("\nThere are "+c1a3.size() + " elements: \n"+c1a3); System.out.print("\nEnter id of student to delete:"); id = kb.next(); s = new Student(name,0); if(c1a3.containsKey(id)) c1a3.remove(id); else System.out.println("Student not found"); System.out.println("\nThere are now "+c1a3.size() + " elements \n"+c1a3); }

}

Page 193: Javanotes

This chapter includes a good sample of algorithms used

in computer science. Sorts and searches are the most

important at your level - but the rest gives an idea of

how an algorithm is a simple solution to the problem.

Although much of the work is already done in java and

you can find ready made methods which implement these

functions a good knowledge of algorithms is required so

as to give you practice of how to solve your own

customised problems and derive a good algorithm.

Algorithms

Page 194: Javanotes

The Idea of an Algorithm

Supposed you were asked to fill a 3 x 3 magic square in such a

way that when adding the values in each row, in each column

and even the two diagonals their total is always the same.

You may try all possible combinations and after some time you

may discover the right combination.

You can appreciate that if you had a method how to solve it,

You would reach the answer more quickly.

Discovering this method is discovering ―an algorithm‖.

If you try it by trial and error you would be in trouble when

asked to fill a 5x5 or 7x7 grid.

So the best way is to devise an algorithm or general solution to

the problem if it exists.

Page 195: Javanotes

Odd Magic Square Algorithm

For this case, for an odd number of sides the algorithm exists

and can be explained as follows:

1. Start by placing 1 in the middle of the top row

2. Move diagonally right and up as if the top side was connected to the

bottom side and the right side to left side.

3. If the square you arrived into is already taken by another number

move one square below the current position.

4. Continue like that until you finish all the square.

Page 196: Javanotes

Implementation

1. Start by placing 1 in the

middle of the top row

2. Move diagonally right and

up as if the top side was

connected to the bottom

side and the right side to

left side.

3. If the square you arrived

into is already taken by

another number move one

square below the current

position.

4. Continue like that until you

finish all the square.

public class MagicSquare { private static final int SIZE = 3; public static void main (String args[]){ int square[][] = new int[SIZE][SIZE]; int row = 0; int column = SIZE/2; square[row][column] = 1; for(int i = 2; i <= SIZE*SIZE; i++){ row = (row+SIZE-1)%SIZE; column = (column+1)%SIZE; if (square[row][column] != 0){ row = (row+2)%SIZE; column = (column+SIZE-1)%SIZE; } square[row][column] = i; } for(int r = 0; r< SIZE; r++){ for(int c = 0; c <SIZE; c++){ System.out.print("\t"+square[r][c]); } System.out.println(""); } }

}

1

2

3

4

Page 197: Javanotes

Roman Numbers

Supposed we are asked to decode Roman numbers like

MCMXCII to normal Arabic Numbers.

If we try to do this with the first technique that comes in mind

using if statements, the approach would be a bit complicated.

If we try to think a bit further and device a better solution

using a symbol-state table, the approach would be much

neater.

Assume Roman numerals to be composed of the following

elements, never more than one from each consecutive list:

Page 198: Javanotes

Roman Automata

The logic of the program is contained in the following symbol-state table:

Take for example the Roman number CIX, Begin with a value of zero. You are in

a state 00 (where the arrow is). Look downfrom symbol C and find 00:03 which

says add 100 to the current value and move to state 03. now in state 3 look

down the symbol I and find 1:11. So add 1 to the value (100+1 = 101) and

move to state 11. Finally in state 11 look down from the symbol X and find

8:15. So you add 8 (101+8 = 109) and move to state 15 a row of empty cells.

There are no more Roman digits, so CIX decodes as 109.

Page 199: Javanotes

The Coding

public static int romanToArabic(String r){ int state, token, number; state = token = number = 0; boolean valid = true; for(int i = 0; i< r.length() && valid; i++){ for(token = 0; token <7 && r.charAt(i) != symbol[token];++token); long entry = automata[state][token]; valid = (entry != 0); number += entry / 100; state = (int) entry % 100; } return (valid)? number: -1; }

}

public class Roman { private static char symbol[] = { 'M', 'D', 'C', 'L', 'X', 'V', 'I' }; private static final long automata[][] = { {100000, 50001, 10003, 5007, 1006, 512, 111, 0}, { 0, 0, 10002, 5007, 1006, 512, 111, 0}, { 0, 0, 10004, 5007, 1006, 512, 111, 0}, { 80005, 30005, 10004, 5007, 1006, 512, 111, 0}, { 0, 0, 10005, 5007, 1006, 512, 111, 0}, { 0, 0, 0, 5007, 1006, 512, 111, 0}, { 0, 0, 8010, 3010, 1009, 512, 111, 0}, { 0, 0, 0, 0, 1008, 512, 111, 0}, { 0, 0, 0, 0, 1009, 512, 111, 0}, { 0, 0, 0, 0, 1010, 512, 111, 0}, { 0, 0, 0, 0, 0, 512, 111, 0}, { 0, 0, 0, 0, 815, 315, 114, 0}, { 0, 0, 0, 0, 0, 0, 113, 0}, { 0, 0, 0, 0, 0, 0, 114, 0}, { 0, 0, 0, 0, 0, 0, 115, 0}, { 0, 0, 0, 0, 0, 0, 0, 0}, };

Page 200: Javanotes

The main Class

import java.util.*; public class UseRoman{ public static void main (String args[]){ Scanner kb = new Scanner(System.in); System.out.print("Enter a Roman numeral: "); String entry= kb.next(); int n; if ((n = Roman.romanToArabic(entry)) != -1) System.out.println(n); else System.out.println("Error in Roman numeral"); }

}

Page 201: Javanotes

Back to the Future

Now we need to translate back from Arabic to Roman

numerals. If we analyze again the Roman literals table, we see

that the same pattern is repeated for units, tens, hundreds and

thousands, the only thing that changes is the symbols for the

singles (I, X, C and M} and for the fivers (V, L and D). For the

teners the symbols are X, C and M.

Page 202: Javanotes

Implementation

switch(digit){ case 1: literal = ""+s; break; case 2: literal = ""+s+s; break; case 3: literal = ""+s+s+s; break; case 4: literal = ""+s+f; break; case 5: literal = ""+f; break; case 6: literal = ""+f+s; break; case 7: literal = ""+f+s+s; break; case 8: literal = ""+f+s+s+s; break; case 9: literal = ""+s+t; } result = literal+result; }while(n > 0); return result; } else return "Over the end of the Roman Empire"; }

}

public class Arabic{ private static final char [] singles = {'I', 'X', 'C', 'M'}; private static final char [] fivers = {'V', 'L', 'D',' '}; private static final char [] teners = {'X', 'C', 'M',' '}; public static String arabicToRoman(int n){ int count = 0; String result = ""; if(n<4000){ do{ char s = singles[count]; char f = fivers[count]; char t = teners[count++]; String literal = ""; int digit = n%10; n = n/10;

Page 203: Javanotes

Testing: Roman-Arabic-Roman

To test the previous programs thoroughly we go back to and

front from Arabic to Roman and vice versa. If everything is

correct we should arrive to the original number.

public class TestRoman{ public static void main (String args[]){ boolean test = true; int pos = 0; for (int n = 1; n < 4000 && test; n++){ if (Roman.romanToArabic(Arabic.arabicToRoman(n))!=n){ test = false; pos = n; } } if (test) System.out.println("Test Passed "); else System.out.println("Test Failed first time on: "+pos); }

}

Page 204: Javanotes

Recursive Binary

An elegant solution to decimal to binary conversion is given by

a recursive approach. In this conversion, we continually divide

by 2 the quotient and take the remainder:

import java.util.*; public class Bins{ public static void main(String args[]){ Scanner kb = new Scanner(System.in); System.out.print("Enter Number in decimal: "); int dec = kb.nextInt(); System.out.println(dec +" in binary is: "+toBinary(dec)); } private static String toBinary(int n){ if (n == 0) return ""; else return toBinary(n/2)+(n%2); }

}

Page 205: Javanotes

Bubble Sort

The simplest (but slightly

inefficient) sorting

algorithm is the bubble

sort.

In the first pass it compares

two consecutive elements and

swap these if they are out of

order, or leave them as they

are if they are in order.

It thus bubbles the smallest

(lightest) element to the top.

This procedure is repeated

with the rest of the list until

all the list has been sorted.

Page 206: Javanotes

Time and Space Complexity

Time complexity refers to the proportionality of the time

requirements of the algorithm with n, the number of elements

on which the algorithm is performed on.

It is a measure of the scalabilty of the algorithm. In other

words, what will happen to the time required to perform the

algorithm if the number of elements double, say.

Most algorithms require n comparisons for n passes so their

complexity is O(N2).

Space complexity is the additional space required, In these

only one swapping variable.

Most algorithms require just a space complexity of 1,

independent of the number of elements used.

Page 207: Javanotes

Implementation

import java.util.*; public class Bubble{ public static void main(String args[]){ Scanner kb = new Scanner(System.in); System.out.print("Enter String to be sorted: "); StringBuffer s = new StringBuffer(kb.next()); System.out.println("Sorted string is: "+binSort(s)); } private static StringBuffer binSort(StringBuffer s){ for(int j = 0; j< s.length()-1;++j){ for(int k = s.length()-1;j<k;--k){ if (s.charAt(k-1) > s.charAt(k)){ char temp = s.charAt(k-1); s.setCharAt(k-1,s.charAt(k)); s.setCharAt(k,temp); } } } return s; }

}

Worst Time Complexity O(N2) Average Time Complexity O(N2)

Space Complexity O(1)

Page 208: Javanotes

Selection Sort

This is a simple algorithm, very

similar to the procedure adopted

by humans when sorting a bunch

of papers.

On the first run the minimum is found

from the list and swapped with the

first element.

Then the next smallest element is

chosen and swapped with the second

element.

So and so forth with all the elements

in the array.

Page 209: Javanotes

Implementation

public class Selection{ public static void main(String args[]){ int [] nums = {12, 3, 7, 4, 8}; sSort(nums); for(int i =0; i<nums.length; i++) System.out.print(nums[i]+" "); } public static void sSort(int[] x) { for (int i=0; i<x.length-1; i++) { int minIndex = i; for (int j=i+1; j<x.length; j++) { if (x[minIndex] > x[j]) { minIndex = j; } } if (minIndex != i) { int temp = x[i]; x[i] = x[minIndex]; x[minIndex] = temp; } } }

}

Worst Time Complexity O(N2) Average Time Complexity O(N2)

Space Complexity O(1)

Page 210: Javanotes

Quicksort

The sorting algorithm called Quicksort was devised by C.A.R.

Hoare and consists of the following procedure:

Take a string of letters to sort:

Set a pointer at either end of the list and a pivot at the middle

of the list.

Move j to the left until it reaches an element less than the one

at the pivot:

Move i to the right until it reaches an element greater than the

one at the pivot:

Swap element at i with that at j

And continue swapping as necessary , until j is less than i

At this stage it is true to say that all elements on the left of i

are less than the element at i, and all elements on the right are

greater than it. We have sorted just one element but we can

apply the same algorithm recursively on both halves on either

side of i;

Page 211: Javanotes

Quicksort Scenarios

Average Time Complexity O(Nlog(N)) Worst Time Complexity O(N2)

Space Complexity O(log(N))

Page 212: Javanotes

Implementation

private static int partition (StringBuffer s, int left, int right) { int i = left, j = right; char tmp; int pivot = (left + right) / 2; while (i <= j) { while (s.charAt(i)< s.charAt(pivot)) i++; while (s.charAt(j) > s.charAt(pivot)) j--; if (i <= j) { tmp = s.charAt(i); s.setCharAt(i,s.charAt(j)); s.setCharAt(j,tmp); i++; j--; } } return i; }

}

import java.util.*; public class Quick{ public static void main (String args[]){ Scanner kb = new Scanner(System.in); System.out.print("Enter String to be sorted: "); StringBuffer s = new StringBuffer(kb.next()); qSort(s,0,s.length()-1); System.out.println("Sorted string is: "+s); } private static void qSort (StringBuffer s, int left, int right) { int index = partition(s, left, right); if (left < index - 1) qSort(s, left, index - 1); if (index < right) qSort(s, index, right); }

Page 213: Javanotes

Mergesort - Divide and Conquer

In computer science, merge sort or mergesort is a

sorting algorithm for rearranging lists (or any other

data structure that can only be accessed

sequentially, e.g. file streams) into a specified

order. It is a particularly good example of the

divide and conquer algorithmic paradigm. The

algorithm was invented by John von Neumann in

1945.

Conceptually, merge sort works as follows:

1. Divide the unsorted list into two sublists of about half the

size

2. Sort each of the two sublists

3. Merge the two sorted sublists back into one sorted list.

Page 214: Javanotes

Algorithm

mergesort

mergesort

mergesort

merge

merge

merge

public class MSort{ public static void main (String args[]){ int [] nums = {38,27,43,3,9,82,10}; MergeSort.mergeSort(nums); for(int i = 0; i < nums.length; i++) System.out.print(" "+nums[i]); }

}

Worst Time Complexity O(nlog(N))

Average Time Complexity O(nlog(N))

Space Complexity O(N)

Page 215: Javanotes

Implementation

private static void merge ( int[ ] a, int[ ] tmp, int lPos, int rPos, int rEnd ) { int lEnd = rPos - 1; int tPos = lPos; int numElements = rEnd - lPos + 1; while( lPos <= lEnd && rPos <= rEnd ) if( a[lPos] < a[rPos] ) tmp[tPos++] = a[lPos++]; else tmp[tPos++] = a[rPos++]; while( lPos <= lEnd ) tmp[tPos++] = a[ lPos++ ]; while( rPos <= rEnd ) tmp[tPos++] = a[rPos++]; for( int i = 0; i < numElements; i++, rEnd-- ) a[ rEnd ] = tmp[rEnd ]; }

}

public class MergeSort{ public static void mergeSort( int[] a ) { int [] tmp = new int[ a.length ]; mergeSort( a, tmp, 0, a.length - 1 ); } private static void mergeSort ( int[ ] a, int[ ] tmp,int left, int right ) { if( left < right ) { int center = ( left + right ) / 2; mergeSort( a, tmp, left, center ); mergeSort( a, tmp, center + 1, right ); merge( a, tmp, left, center + 1, right ); } }

Page 216: Javanotes

Insertion Sort

Insertion sort algorithm is similar to bubble sort. But insertion sort is more efficient

than bubble sort because in insertion sort the elements comparisons are less as

compare to bubble sort.

In insertion sorting algorithm compare the value until all the prior elements are

lesser than compared value.

This means that the all previous values are lesser than compared value.

Insertion sort is a good choice for a small number of nearly-sorted values.

There are more efficient algorithms such as quick sort, heap sort, or merge sort

for large values .

Positive feature of insertion sorting:

It is simple to implement

It is efficient on (quite) small data sets

It is efficient on data sets which are already nearly sorted.

It is very inefficient for large unsorted arrays since it involves large movement of data

Page 217: Javanotes

Implementation

public class InsertionSort{ public static void main (String args[]){ int [] nums = {12,3,2,7,8,9,1,5}; ISort.insertionSort(nums); for(int i = 0; i < nums.length; i++) System.out.print(" "+nums[i]); }

}

public class ISort{ public static void insertionSort(int array[]){ for (int i = 1; i < array.length; i++){ int j,tmp; for(j=i,tmp=array[i]; j > 0 && array[j-1] > tmp;j--) array[j] = array[j-1]; array[j] = tmp; } }

}

Worst Time Complexity O(N2) Average Time Complexity O(N2)

Space Complexity O(1)

Page 218: Javanotes

Linear Search

Linear searching is a way to find if a certain element (number

, string , etc. ) is in a specified list.

The list can be in any order, or be completely jumbled and this

search will find the element if it is there.

If the element is found we can return the index where the

element is located in the list.

If the element is not found we can return -1.We can assume no

list will ever have an negative number as an index.

Our approach will be to check every element in the list

consecutively to see if it is what we are looking for.

We will use a loop to cycle through the array.

Page 219: Javanotes

Implementation

Time Complexity O(n)

Space Complexity O(1)

package DataStructures; import java.util.*; public class LSearch{ public static int search (Vector <Students.Student> klassi,String name){ for(int pos = 0;pos<klassi.size(); pos++){ if(name.equals(klassi.get(pos).getName())) return pos; } return -1; }

}

import java.util.*; public class UseLinear{ public static void main(String args[]){ Vector <Student> c1a3 = new Vector<Student>(); c1a3.addElement(new Student("John Cutajar",78)); c1a3.addElement(new Student("Maria Cutajar",98)); c1a3.addElement(new Student("Martin Cutajar",90)); c1a3.addElement(new Student("Martina Cutajar",76)); int where = LSearch.search(c1a3,"Martin Cutajar"); if(where > 0) System.out.println(c1a3.get(where)); else System.out.println("Student not found"); }

}

Page 220: Javanotes

Binary Search

A fast way to search a sorted array is to use a binary search.

The idea is to look at the element in the middle.

If the key is equal to that, the search is finished.

If the key is less than the middle element, do a binary search on the first

half.

If it's greater, do a binary search of the second half.

Time Complexity O(log(n))

Space Complexity O(1)

Page 221: Javanotes

Implementation

public static int binarySearch ( Comparable [ ] a, Comparable x ) { int low = 0; int high = a.length - 1; int mid; while( low <= high ) { mid = ( low + high ) / 2; if( a[ mid ].compareTo( x ) < 0 ) low = mid + 1; else if( a[ mid ].compareTo( x ) > 0 ) high = mid - 1; else return mid; } return -1; }

}

public class BinarySearch { public static void main( String [ ] args ) { int SIZE = 8; int index; Comparable [ ] a = new Integer [ SIZE ]; for( int i = 0; i < SIZE; i++ ) a[ i ] = new Integer( i * 2 ); for( int i = 0; i < SIZE * 2; i++ ) if ((index = binarySearch(a,new Integer(i))) > 0) System.out.println( "Found "+i+" at "+index); }

Page 222: Javanotes

Towers of Hanoi

The Towers of Hanoi is a mathematical puzzle. It consists of

three rods, and a number of disks of different sizes which can

slide onto any rod.

The puzzle starts with the disks neatly stacked in order of size

on one rod, the smallest at the top, thus making a conical

shape.

The objective of the puzzle is to move the entire stack to

another rod, obeying the following rules:

Only one disk may be moved at a time.

Each move consists of taking the upper disk from one of the rods and

sliding it onto another rod, on top of the other disks that may already be

present on that rod.

No disk may be placed on top of a smaller disk.

Page 223: Javanotes

Implementation

public class Hanoi { public static void main (String args[]){ hanoi(5,'A','C','B'); } public static void hanoi(int n, char source, char dest, char by){ if (n==1) System.out.println("Move "+n+" from "+source+" to "+ dest); else{ hanoi(n-1, source, by, dest); System.out.println("Move "+n+" from "+source+" to "+ dest); hanoi(n-1, by, dest, source); } }

}

Page 224: Javanotes

Exceptions are used in programs to make the program more robust

and resilient to errors. By using exceptions the programmer can

handle runtime errors in a graceful manner and not giving the user a

useless debug information.

Java stores data on files by means of streams. The java FileStream

stores bytes or array of bytes into a file. There then exist which

serialize data to bytes:

DataStreams : to serialize primitive data types to bytes

Buffers and writers for text conversion, or

ObjectStreams: to convert objects to stream

Exceptions and IO Streams

Page 225: Javanotes

Exceptions

An exception represents an error condition that can occur

during the normal course of program execution.

When an exception occurs, or is thrown, the normal sequence

of flow is terminated. The exception-handling routine is then

executed; we say the thrown exception is caught.

If you do not catch an exception, the exception propagates to

the OS, giving a stack trace of the exception

We don't want the user to be prompted with a stack trace and

the display of the listing. We want the program to be robust

and resilient to errors, do its good practice to use exception

handling:

Page 226: Javanotes

Exception Handling

Page 227: Javanotes

Getting Exception Information

There are more methods we can call to get information about

the thrown exception:

getMessage()

printStackTrace()

A single try-catch statement can include multiple catch blocks,

one for each type of exception.

catch (InputMismatchException e){ System.out.println(e.getMessage()); e.printStackTrace(); }

Page 228: Javanotes

Exception Handling

import java.util.*; public class tryExcept{ public static void main (String args[]){ Scanner kb = new Scanner(System.in); boolean valid; int input =0;; do{ valid = true; System.out.print("Enter and integer: "); try { input = kb.nextInt(); } catch (InputMismatchException e){ System.out.println("What sort of integer was that?"); kb.next(); //empty buffer valid = false; } }while(!valid); if(input%2 == 0) System.out.println("Number is even "); else System.out.println("Number is odd"); }

}

try this

if it fails do

this block

Not OK OK

Page 229: Javanotes

The finally Block

There are situations where we need to take certain actions

regardless of whether an exception is thrown or not.

We place statements that must be executed regardless of

exceptions in the finally block.

int num =0; int total = 0; try { num = kb.nextInt(); } catch (InputMismatchException e){ System.out.println("Must be an Integer: "); num = 0; } finally { total+=num;

}

Page 230: Javanotes

Multiple Catches

A single try block can have multiple catches attached to it so

as to take different actions according to the type of exception

raised:

System.out.print("Enter an integer: "); try { nums[i++] = kb.nextInt(); } catch (InputMismatchException e){ System.out.println("Must be an integer"); } catch (ArrayIndexOutOfBoundsException e){ System.out.println("Too many integers"); } catch (Exception e){ System.out.println("However something's wrong");

}

put the most generic exception

last

Page 231: Javanotes

Less or More Generic

Throwable

Error

Exception

AssertionError

RuntimeException

IOException RuntimeException

IllegalArgumentException

NumberFormatException

more

generic

less

generic

There are over 60 classes in this

hierarchy.

NullPointerException

Page 232: Javanotes

Propagating Exceptions

Instead of catching a thrown exception by using the try-catch

statement, we can propagate the thrown exception back to the

caller of our method.

The method header includes the reserved word throws.

import java.util.*; public class Thrower{ public static void main (String args[])throws NumberFormatException{ Scanner kb = new Scanner(System.in); int num = kb.nextInt(); }

}

Page 233: Javanotes

Exception Thrower

A method which may throw an exception, either directly or

indirectly, is called an exception thrower. An exception thrower

might be one of two types:

Exception thrower–catcher: which includes a matching catch block.

Exception propagator: which does not contain a matching catch block.

A method may be a catcher of one exception and a

propagator of another.

We can write a method that throws an exception directly, i.e.,

this method is the origin of the exception.

Use the throw reserved to create a new instance of the

Exception or its subclasses.

The method header includes the reserved word throws.

Page 234: Javanotes

Example import java.util.*; public class Thrower{ public static void main (String args[]){ methodA(); } public static void methodA(){ try{ methodB(); } catch(Exception e){ System.out.println("Problem: "+e.getMessage()); } } public static void methodB()throws Exception{ methodC(5); } public static void methodC(int n) throws Exception{ if (n > 4){ throw new Exception("n is too low"); } }

}

catcher

propagator

thrower

Page 235: Javanotes

Types of Exceptions

There are two types of exceptions:

Checked. (example: file handling)

Unchecked. (example: reading keyboard entry)

A checked exception is an exception that is checked at compile

time.

All other exceptions are unchecked, or runtime, exceptions. As

the name suggests, they are detected only at runtime.

When calling a method that can throw checked exceptions

Use the try-catch statement and place the call in the try block, or

Modify the method header to include the appropriate throws clause.

When calling a method that can throw runtime (unchecked)

exceptions, this is optional

Page 236: Javanotes

User-Defined Exceptions

Using the standard exception classes, we can use the getMessage() method to

retrieve the error message.

By defining our own exception class, we can pack more useful information

For example, we may define a OutOfStock exception class and include

information such as how many items to order

AgeInputException can be defined as a subclass of Exception and includes

public methods to access three pieces of information it carries: lower and

upper bounds of valid age input and the (invalid) value entered by the user.

public class MyException extends Exception{ public MyException(){ super("Sorry not my Type"); }

}

catch (MyException e){ System.out.println(e.getMessage());

}

Page 237: Javanotes

Assertions

The syntax for the assert statement is:

assert <boolean expression>;

where <boolean expression> represents the condition that must be true

if the code is working correctly. If the expression results in false, an

AssertionError (a subclass of Error) is thrown.

Debugging error checking - assert

Use assert statements liberally to debug your own code. Assertions are

very easy to use and are very helpful during testing. You can leave them

in your final code.

Off at runtime.

The disadvantage of assertions is that they are turned off by default

during execution.

Page 238: Javanotes

Error Processing

Error in user input or action

Allow user to recover gracefully.

If the user makes an error in input, give appropriate feedback and

allow them to correct the error if possible.

Informative message.

It's important to give specific feedback that allows them to correct their

problem. For example a program that produced an "Error in processing"

error message. There is no hint as to whether is was a user input error or

a bug in the program. Bad.

Programmer errors - throw an exception

If you write code that is going to be used by other programmers, it is

especially important to detect errors and throw an exception.

Page 239: Javanotes

I/O Streams

An I/O Stream represents an input source or an output destination.

A stream can represent many different kinds of sources and destinations,

including disk files, devices, other programs, and memory arrays.

Streams support many different kinds of data, including simple bytes,

primitive data types, localized characters, and objects.

Some streams simply pass on data; others manipulate and transform the

data in useful ways.

Page 240: Javanotes

File Input and Output - The File Class

To operate on a file, we must first create a File object (from

java.io).

import java.io.*;

File inFile = new File(“data.dat”); File inFile = new File(“c:\\data.dat”);

Absolute path

file created in current working directory where java project

resides

Page 241: Javanotes

File Flushing and Closing

flush() makes sure everything you have written to file so far is committed to

the hard disk, and the expanded file length is also committed to the disk

directory, with the updated lastModified timestamp committed too.

If you crash the system later, you know at least that much is guaranteed to

be there on disk waiting for you when you reboot.

Since flushing is done automatically when a file is closed, it is good

practice to close the file after use, such that all updates that were done to

the file will be transferred from the temporary memory buffer to disk.

It is also good practice not to leave the file open for the whole program but

just read it contents and close it, working in memory.

You then save again to file before closing.

Page 242: Javanotes

Low-Level File I/O

To read data from or write data to a file, we must create one of the Java

stream objects and attach it to the file.

A stream is a sequence of data items, usually 8-bit bytes.

Java has two types of streams: an input stream and an output stream.

An input stream has a source (say a file) from m which the data items come,

which allows us to output a sequence of bytes; values of data type byte.

An output stream has a destination (say a file) to which the data items are going

which allows us to read in an array of bytes.

FileOutputStream and FileInputStream are two stream objects that facilitate

file access.

Page 243: Javanotes

Example

import java.io.*; public class Writing{ public static void main (String args[]) throws Exception{ File outFile = new File("data.dat"); FileOutputStream outStream = new FileOutputStream(outFile); byte [] primes = {1, 2, 3, 5, 7, 11, 13, 17}; outStream.write(primes); outStream.close(); }

}

import java.io.*; public class Reading{ public static void main (String args[]) throws Exception{ File inFile = new File("data.dat"); FileInputStream inStream = new FileInputStream(inFile); int fileSize = (int)inFile.length(); byte [] numbers = new byte[fileSize]; inStream.read(numbers); System.out.print("The primes are: "); for(int i = 0; i < fileSize; i++) System.out.print(" "+numbers[i]); inStream.close(); }

}

Page 244: Javanotes

High-Level File I/O Streams

FileOutputStream and DataOutputStream are used to output

primitive data values whilst FileInputStream and

DataInputStream are used to input primitive data values

To read the data back correctly, we must know the order and

type of the data stored and their data types

Page 245: Javanotes

Output Stream Example

import java.io.*; public class DataOut{ public static void main (String args[]) throws IOException{ File oFile = new File("data.dat"); FileOutputStream oFStream = new FileOutputStream(oFile); DataOutputStream oDStream = new DataOutputStream(oFStream); oDStream.writeInt(32); oDStream.writeLong(4500000000L); oDStream.writeFloat(32.5F); oDStream.writeDouble(3.142567D); oDStream.writeChar('J'); oDStream.writeBoolean(true); oDStream.close(); }

}

Page 246: Javanotes

Input Stream Example

import java.io.*; public class InData{ public static void main (String args[]) throws IOException{ File iFile = new File("data.dat"); FileInputStream iFStream = new FileInputStream(iFile); DataInputStream iDStream = new DataInputStream(iFStream); System.out.println(iDStream.readInt()); System.out.println(iDStream.readLong()); System.out.println(iDStream.readFloat()); System.out.println(iDStream.readDouble()); System.out.println(iDStream.readChar()); System.out.println(iDStream.readBoolean()); iDStream.close(); }

}

Page 247: Javanotes

Random Access Files

Random access files permit non-sequential, or random, access

to a file's contents.

The following code creates a RandomAccessFile named

cutajar.txt and opens it for both reading and writing:

new RandomAccessFile("cutajar.txt", "rw");

RandomAccessFile supports the notion of a file pointer. The file

pointer indicates the current location in the file.

When the file is first created, the file pointer is set to 0,

indicating the beginning of the file.

Calls to the read and write methods adjust the file pointer by

the number of bytes read or written.

Page 248: Javanotes

File Pointer Methods

In addition to the normal file I/O methods that implicitly move

the file pointer when the operation occurs, RandomAccessFile

contains three methods for explicitly manipulating the file

pointer:

int skipBytes(int) — forward by the specified number of bytes

void seek(long) — Positions the file pointer just before specified byte

long getFilePointer() — Returns location of the file pointer

Page 249: Javanotes

Example

import java.io.*; public class RandomAccess { public static void main(String args[]) throws IOException{ File file = new File("epitaph.txt"); RandomAccessFile raf = new RandomAccessFile(file, "rw"); byte ch = raf.readByte(); System.out.println("Read first character of file: " + (char)ch); System.out.println("Read full line: " + raf.readLine()); raf.seek(file.length()); raf.writeBytes(" ~ an epitaph for himself"); raf.close(); }

}

Page 250: Javanotes

Textfile Input and Output

Instead of storing primitive data values as binary data in a

file, we can convert and store them as a string data.

This allows us to view the file content using any text editor To

output data as a string to file, we use a PrintWriter object.

To input data from a textfile, we use FileReader and

BufferedReader classes or the Scanner class.

Using

BufferedReader

Page 251: Javanotes

PrintWriter Example

import java.io.*; public class TextOut{ public static void main (String args[]) throws IOException{ File outFile = new File("epitaph.txt"); FileOutputStream outStream = new FileOutputStream(outFile); PrintWriter writer = new PrintWriter(outStream); writer.println ("He slept beneath the moon,"); writer.println ("He basked under the sun,"); writer.println ("Lived a life of going to do,"); writer.println ("and died with nothing done."); writer.close(); }

}

Page 252: Javanotes

BufferedReader Example

import java.io.*; public class TextIn{ public static void main (String args[]) throws IOException{ File inFile = new File("epitaph.txt"); FileReader inReader = new FileReader(inFile); BufferedReader reader = new BufferedReader(inReader); do{ System.out.println(reader.readLine()); }while(reader.ready()); reader.close(); }

}

Page 253: Javanotes

Example Writing Data as Text

import java.io.*; public class ScannerOut{ public static void main (String args[]) throws IOException{ File outFile = new File("report.txt"); FileOutputStream outStream = new FileOutputStream(outFile); PrintWriter writer = new PrintWriter(outStream); writer.println ("John Cutajar\n65.4"); writer.println ("Martina Cutajar\n97.34"); writer.println ("Maria Cutajar\n98.34"); writer.println ("Martin Cutajar\n99.345"); writer.close(); }

}

Page 254: Javanotes

Example Using the Scanner Class

import java.io.*; import java.util.*; public class ScannerIn{ public static void main (String args[]) throws IOException{ Scanner reader = new Scanner(new File("report.txt")); reader.useDelimiter("\n"); while(reader.hasNext()){ System.out.print(reader.next()+" with average: "); try{ System.out.println(Float.parseFloat(reader.next())); } catch(NumberFormatException e){ String found = reader.next(); System.out.println("Expected a float but found: "+found); } } reader.close(); }

}

Using Scanner Class

(from sdk 1.5)

Page 255: Javanotes

Object File I/O

It is possible to store objects just as easily as you store

primitive data values.

We use ObjectOutputStream and ObjectInputStream to save

to and load objects from a file.

To save objects from a given class, must implement the

Serializable interface.

Page 256: Javanotes

Storing Objects or Lists

import java.util.*; import java.io.*; public class StudentFileOut{ public static void main (String args[]) throws IOException{ Scanner kb = new Scanner(System.in); kb.useDelimiter("\n"); Map <String,Student> c1a3 = new TreeMap <String,Student>(); System.out.print("Enter name Student File: "); String filename = kb.next(); File dosFile = new File(filename); FileOutputStream myStream = new FileOutputStream(dosFile); ObjectOutputStream studentFile = new ObjectOutputStream(myStream); Student s; String name,id; do{ System.out.print("Enter name & surname or \"end\": "); name = kb.next();

if (!name.equals("end")){ System.out.print("ID Card Number: "); id = kb.next(); System.out.print("Enter mark: "); int mark = kb.nextInt(); s = new Student(name,mark); c1a3.put(id,s); } }while (!name.equals("end")); studentFile.writeObject(c1a3); studentFile.close(); }

}

Page 257: Javanotes

Reading Object Files

import java.util.*; import java.io.*; public class StudentFileIn{ public static void main (String args[]){ Scanner kb = new Scanner(System.in); kb.useDelimiter("\n"); Map <String,Student> c1a3 = new TreeMap <String,Student>(); System.out.print("Enter name Student File: "); String filename = kb.next(); ObjectInputStream studentFile = null; try{ File dosFile = new File(filename); FileInputStream myStream = new FileInputStream(dosFile); studentFile = new ObjectInputStream(myStream); c1a3 = (TreeMap <String,Student>) studentFile.readObject(); studentFile.close(); } catch(Exception e){ System.out.println("Error in reading file"); } System.out.println(c1a3); }

}

Ignore compiler

warnings

Page 258: Javanotes

import java.io.*; import java.util.*; public class CheckFiles{ public static void main (String args[]) throws Exception{ ArrayList <Student> klassi = new ArrayList<Student>(); File myFile = new File("studenti.dat"); if (myFile.exists()){ FileInputStream myFStream = new FileInputStream(myFile); ObjectInputStream myOStream = new ObjectInputStream(myFStream); try{ klassi = (ArrayList<Student>)myOStream.readObject(); System.out.println("Read succesfully."); }catch(EOFException eof){ System.out.println("File is empty"); } myOStream.close(); } else{ System.out.println("File not found "); }

Checking Files

At the start of a

program one

must check if the

file exists and

then if it is empty

or not.

Writing will

automatically

create a file if it

does not exist.

//... process the ArrayList FileOutputStream myFStream = new FileOutputStream(myFile); ObjectOutputStream myOStream = new ObjectOutputStream(myFStream); myOStream.writeObject(klassi); myOStream.close(); }

}

Page 259: Javanotes

Using Filters and Directories

Using filters one can display a selection of files from a folder.

Below is an example how to create a folder and display its

contents.

import java.io.*; public class listOnly implements FilenameFilter { private String extension; public listOnly(String ext) { extension = "." + ext; } public boolean accept(File dir, String name) { return name.endsWith(extension); }

}

filter class to list files with

some extensions

only

Page 260: Javanotes

Example

import java.io.*; import java.util.*; public class UseFiles{ public static void main (String args[])throws Exception{ File dir = new File("lots"); // create a file directory to store lots of files dir.mkdir(); for(int i = 0; i < 10; i++){ // fill it with two types of files File typeA = new File("lots/file"+i+".ex1"); FileOutputStream a = new FileOutputStream(typeA); a.write(i); a.close(); File typeB = new File("lots/file"+i+".ex2"); FileOutputStream b = new FileOutputStream(typeB); b.write(10+i); b.close(); } FilenameFilter halfOfThem = new listOnly("ex1"); // list some files using a filter String [] directory = dir.list(halfOfThem); for ( String s : directory) System.out.println(s); }

}


Recommended