JAVA Notes
JAVA Notes
Clean Code: Make classes and methods small and only have single responsibility.
Class: Contains members: method, Fields/Data members(Instance/Static variables), constructors, Blocks, Inner classes, etc.
- Classes exist in the package.
Name a class:
1. The first letter Should capital.
2. If the class name more than one word:
Main Class (tester programe/tester class) : The class who contains the Main Method.
-The name of MainClass can be any name.
-it should be always static.
- accessor = getter
Method Header/ Method Signature:
5- Method Name: The first letter of the first word in any name in the java should be small letter, expect class name. The first letter of the
second and other words can be capital.
- The name of main method must be main.
6. Parameter/param(Formal Parameter): Variables in the method definition. Located inside the brackets. It can receives a value when the
method is called and the value won’t affect the actual parameter (call-by-value). And it is a local variable.
- The method can hold more than one parameter.
- you don't need a return type to put a parameter. You can have void with parameters.
-note: postcondition: is the output of the method.
-note: precondition: something is true before the method is called. NOTE: PART TWO OF METHODS EXPLAINED AFTER OVERRIDING.
Print Statement: Displays output.
.err.
Reference Types:
Class
Interface
Array
String
Logical Operators:
&&: and. Both terms should be true. and
!: not.
not
-These Operators for primitive values. Also, objects support == and != operators.
Operators:
- Operate between variables and values.
Operator Meaning Example: Int x =22;
System.out.println(x+1); //Output: 23
+ Addition x=x+1;
System.out.println(x=x+1);
- Subtraction System.out.println(x-1); //Output: 21
* Multiplication System.out.println(x*8); //Output: 176
/ Division System.out.println(x/4); //Output: 5
System.out.println(--x); //Output: 21
Use the current value of number. Then decrease it by 1 for the next statement.
-- Decrement System.out.println(x--); //Output: 22
System.out.println(x); //Output: 21
System.out.println(Math.log10(100)); //Output: 2
-- Formula:
Example:
Math.log10(value) Logarithm, base 10
--
radian to degree:
Math.toRadians(value) Convert radians to degrees
Note: = 3.14
System.out.println(Math.random());
Math.random() Random double between 0 and 1 System.out.println((int)(Math.random()*100)); //Output: the result will be
between 1 to 100
Method Name for a constant Meaning
Math.E 2.7182818…
Math.PI 3.1415926…
Class: is a template for the objects.
Object: is an instance (copy) of a class. With more details.
- When you make an object, it inherits all the variables and methods from the class.
- Sometimes we make a whole class just to make an object of it: Bean class.
- objects written in the main method.
- You can make an object of:
1. The main class.
2. Any class in the same package.
3. Any class outside your package by importing the class (Explained later).
Note: to create a constructor fast: right click then generate then insert code then constructor. (alt + ins)
Encapsulation: means that the data and actions are combined into a single item which is a Class.
Reference Type:
- Class: is a Reference Type.
- a variable of an class: Its name a reference variable; Because, we use it to reference to an Copy of the class/object, (object reference
variable).
- Default value of any Reference variable is null.
- You can equal a class variable to another, same as any other variables types.
Reference an object:
Make a new object and assign it to the object reference variable using the new operator
-write an argument inside the brackets if there is a parameter in the constructor.
-The class variable can be declared first or in the same line with object creation.
- Static Method: You can invoke it without making an object. Just by using the class name with the method name:
ClassName.methodName(); or just by the method name : methodName();.
To use the class:
Restaurant p = new Restaurant();
p.setName("Alvin");
System.out.println("The name is " + p.getName());
System.out.println(p.toString());
// array of object
int size = 5;
Restaurant[] rest = new Restaurant[size];
// use foor loop
rest[0] = new Restaurant("OPQ","Serdang",30);
rest[1] = new Restaurant("LMN","Kajang",22);
System.out.println(rest[0].toString());
System.out.println(rest[1].toString());
*/
How to make an object of a class outside the package:
1. Import the class: Import strucher.package.Class; -You can import the whole package by using * like:
Import java.util*;
Note: your class shouldn’t be the same name as the imported class.
Note: to import all the classes and interfaces from a package write: import stucher.package.*;
Date Class (java.util.Date): Prints the right moment date in your computer.
What if the file already exists or the computer don’t allow you to create the file on some places?
To check we use a method from the File class called: createNewFile().
- If there is no one already with the same name and the computer allow you to create.: It will create the file.
- If there is one already with the same name or the computer don’t allow you to create: It won’t create the file and your
project gonna collapse to prevent that from happing we use: try and catch: tries the code inside try, if there’s any error it
goes to catch and show the error(Exception) and run the code inside catch.
-Sometimes the computer won’t allow you to create files on C drive, but if you run NetBeans as administer then it might create it.
- There’s another method in the File Class called exists(): only to check if the file exists or not.
FileWriter Class (java.io.FileWriter): Access a file to write on it.
- In the object argument: The path of the file, but instead of write all of it, we use the getAbsolutePath() method form the File Class.
Generics
- Writing to the end of a File: // because without this, every time you run PrintWriter class it will overwrite on the file.
- File:
Types of variables:
Local Variable: Declared in the method and the usage of it inside that method. Without default values.
-The parameters considered a local veriables.
Data Members:
Static/Class Variable – Static Field: Declared as Static inside the class but outside the method. To
call it you don’t need an object Just the class name with the variable name: ClassName.variableName;.
Instance Variable/Field – Field - State: Declared inside the class but outside the method. Better to be declared as private. To call it you
need an object: objectReferenceVariable.VariableName;
Note: A static method can access the static variables but can’t access the instance variables.
1. Block
- Method body, class body, etc.
//Note: the end not include in the new string of the sub string.
Substring(index) --> means start the new string after the first index.
replaceAll method:
String s1="My name is Khan. My name is Bob. My name is Sonoo.";
String replaceString=s1.replaceAll("\\s","");
Integer.MAX_VALUE
Integer.MIN_VALUE
- next() :Input data of String type. Reads a String that ends with a whitespace
character.
Random Class (java.util.Random): generate random numbers of int, long, double, float, and boolean value.
- Object Reference Variable:
Methods in Random Class:
General information:
Sequence flow: Statements are executed one after the other in order.
Selection flow chooses among alternative courses of action. E.g.: If statements, switch statements.
- The statement is controlled by the boolean expression.
- Relational/Conditional operator can be used in the boolean expression.
- If there is more than one constraint/condition in the decision making, the logical operators are used to merge
multiple constraint/conditions.
Repetition flow specifies that an action is to be repeated while some condition remains true. E.g.: while statements.
If Statement: checks if an expression (condition) is true or false.
- If the condition is true: run the code inside the if.
- If the condition is false: run the code inside the else.
- If you want you can add more conditions, by else if. Then, if the
condition is false, it will first check the else if conditions if one of
them is right before goes to else.
Use compareTo and compareToIgnoreCase methods to know which came first according to ASCII ordering.
s1.compareTo(s2):
if s1 > s2, it returns positive number
if s1 < s2, it returns negative number
if s1 == s2, it returns 0
Note: you can use another way to compare between two strings,
which is: Integer.compare(s1.compareTo(s2), 0);
- The compare() method of Integer class of java.lang package
compares two integer values (x, y) given
as a parameter and returns the value zero if (x==y), if (x < y) then
it returns a value less than zero and
if (x > y) then it returns a value greater than zero.
Comparable and comparator both are an interface that can be used
to sort the elements of the collection. Comparator interface sort
collection using two objects provided to it,
whereas comparable interface compares" this" refers to the one
objects provided to it.
The Ternary Operator:
do while loop: executes code repeatedly based on boolean condition. Similar to while loop except that the condition is
checked after the statements inside do are executed. so do while loop guarantees the loop execution at least once.
continue: If the code of continue is true; then, don’t run the following code of the loop and go back run from the beginning
of the loop again.
Label: Exit the whole loops that inside the label. Break only exists the loop that include the break, so if there is nested loops,
it will not break all the loops.
Switch statement: checks which of the cases of a variable is true, If all of them are false then go to default.
How:
Make a variable and make cases of the variable.
- To exist the switch statement if one of the cases is true we write in the end of a case : break;
(All the cases and default written inside the switch statement).
Switch statement only takes: byte, short, int, char.
Common Error:
• switch (monthNum) {
case 1:
System.out.println("January");
case 2:
System.out.println("No break");
}
For loop: control flow statement that iterates a part of the program multiple times based on the condition and the times of
the repetition.
How:
1. Write the condition and the repetition inside the for loop bracket().
- Make a variable for the repetition times of the loop: Initialization condition.
- Write the condition.
- Write the variable increment or decrement: Update expression/condition.
2. Write the code you wanna loop inside the for loop curly brackets.
/ condition
Methods examples:
In the main method:
// methods with return value
String str = "Welcome UM";
System.out.print("The number of alphabet U and M in " +
str + " is ");
// System.out.println(getAlphabetUM(str));
int result = getAlphabetUM(str);
System.out.println(result); //The number of alphabet U and
M in Welcome UM is 2
4
5
Print an array:
For loop:
this method can’t be used to modify the value of the element of the array.
-If you change the array size then the old one would be
Notes: //You can add elements together
deleted.
-You can use final for an array then you cannot change the index.
Examples: Split method:
- The split method only use one char and it is for String only.
Multidimensional array:
can have more than one dimensional:
- 2 dim: tables, matrix. [raws][columns].
- 3 dim: 3D.
- to print the 2d: use two for loops. the first One for the
raws another for the columns.
Multidimensional array example:
toString:
Note:
when u create a new array and assign it to an old one, it will have the same memory location with the old one. so if you
change a value in the new array it will also change in the original.
For example:
or you use .clone() method then you can make a copy of the original one and if you change the second array it won’t affect
the original one.
Inheritance: Class takes all the properties of another class and add it to his own class. Except private methods.
SuperClass/ParentClass/BaseClass/ancestor class: The class that gives his properties to another class.
SubClass/ChildClass/DerivedClass/ descendent class: The class that inherits and takes the properties.
-You can use the methods of the SuperClass in the Subclass by the object of the SubClass.
- A subclass automatically has all the instance variables (Fields), static variables and the public methods of superclass. But not private.
public class Animal{
}
public class Mammal extends Animal {
}
public class Dog extends Mammal {
} Inherit from Mammal and Animal.
Notes:
- By default, the empty constructor of the subclass have the empty super constructor of the parent constructor. every constructor in
the child class will run the default constructor of the super class first.
- The child class cannot access private variables, so it must call the mutator or set the variables as protected when declaring them.
Question: How to call the constructor of the grandparent class? Call it in the constructor of parent the call the constructor of parent.
The Object class is the parent class of all the classes in java by default. And every class inherit from the Object class getClass method.
- Class c = getClass(); : getClass() method allows you to return information of a class:
- Example:
if (obj1.getClass() == obj2.getClass())
System.out.println("The objects are belongs to same class");
- c.getName(): will return: package.className
- c.getSimpleName(): will return: className
super keyword: after inherit a class you can call constructors or instance variables or methods from the parent class to
not repeat the code.
“Super” is like “this”
“this”: refers to an instance variable.
“super”: refers to a thing in the super class. And that thing is what you write after super.
The use of super keyword: 2) To access the method of parent class when child class has
1) To access the data members of parent class when both overridden that method.
parent and child class have member with same name. Note: if the method is
final it cannot be
override.
- an override method
cannot change the
return type of the
method definition. Also,
can change private to
public.
Note: When child class
doesn’t override the
parent class method
output: then we don’t need to
black use the super keyword
Output: eating... to call the parent class
white
barking... method.
3) To call the no-arg and parameterized constructor of Notes:
parent class - When u create an object of the child class: parent class
Note: With super(), the superclass no-argument constructor is constructor is executed first and then the child class constructor is
called. With super(parameter list), the superclass constructor executed. The compiler adds super()(which invokes the no-arg
with a matching parameter list is called. constructor of parent class) as the first statement in the
constructor of child class (with parameters or without).
- When u write super then the programme will not invoke it
automatically.
output: - super() must be added to the first statement of constructor.
animal is created - write in the child constructor the super keyword and write in the
dog is created super the variable that will equal the variable of the parent’s
constructor parameter and follow the order.
Overriding: using in the supclass from the superclass the same method with the same signature with adding or changing
whatever code inside the method or inherits the same code and add whatever.
- Overriding comes after inheriting the class. -If the method is Final, it cannot be override.
Note: Right Click on the supclass then generate what methods u want to override.
Overloading method: Using a method with the same name in the same class, but with changing the signature.
Examples:
// to make the type that in the parameter of Apple
constructor equal the type in fruit constructor.
Example part 1
Example part 2
// to make the type that in the parameter of Durian constructor equal the type in fruit constructor.
Abstract Class: Declared using abstract keyword.
It can have all the properties of a normal class and abstract methods(methods without body and cannot be static or private)
we can't create an object of an abstract class. The reference variable is used to refer to the objects of derived classes
(subclasses of abstract class).
- A subclass can be abstract even if its superclass is concrete.
Normal class(non-abstract class): It cannot have abstract methods. It can implement multiple interfaces, but it can extend
only one abstract class.
Interface: It’s a template for classes who inherit from it. The classes inherit the methods and by overriding change them as
what each class needs, by making an implementation for them.
- Only have abstract methods.
- Only have public access modifier.
- Doesn’t have constructors.
- Implements keyword to inherit from an interface, not extends.
- You can’t instantiate an object of an interface directly, Therefore, we use a class which implements the interface or use
a method that will give you as a return an instance of the interface.
- Interface can’t inherit a class. But it can inherit an interface with extends keyword or more than just one interface.
- Class can inherit more than just one interface.
- All variables must be public or static or final.
- by default you can call toString.
- Similar to an abstract class, but the intent of an interface is to specify common behavior for objects. For example,
you can specify that the objects are comparable, edible, cloneable using appropriate interfaces.
- Assigning an object of a derived class to a variable of base class is often called upcasting.
BaseClass a = new BaseClass;
DerivedClass b = new DerivedClass;
Examples:
}
Early Binding: The binding which can be resolved at compile time. When you have the same method in the parent and child
without override it and then call it by object then it will call only the parent class:
superclass A = new superclass();
superclass B = new subclass();
A.print(); //will print the parent class method
B.print(); //will print the parent class method
Late binding: In the late binding or dynamic binding, the compiler doesn’t decide the method to be called. So you override
the method in the child class and then when you make the objects and print it, it will print each one, not only the parent’s
method.
superclass A = new superclass();
superclass B = new subclass();
A.print(); //will print the parent class method
B.print(); //will print the child class method
ADT
You should write:
/**
* What the method is.
* Precondition: what it needs in order to run.
* Postcondition: what will happened after it runs.
* @param , state each parameter in one line.
* @return , state what it will return
*/
System.out.printf Method: display formatted output. NOTE: String.format is the same as printf
The syntax: System.out.printf(format specifiers, item1, item2, ..., items);
-Items must match the format specifiers in order and om exact type.
-writing the Format Specifier letter capital would give you the output in Uppercase.
Example:
- You can use %.2f to specify a floating-point value with two digits after the decimal point.
- Display a number with comma separators by adding a comma in front of a number specifier.
2- Anonymous inner class: has no name. use to override a method of class (abstract or concrete) or interface.
3- Local inner class: Created inside a method. Only available within the method.
Static nested class: It cannot access non-static data members and methods. It can be accessed by outer class name. It can access
static data members of outer class including private.
Java Nested Interface: declared within another interface or class. The nested interface must be referred by the outer interface or
class, It can't be accessed directly.
- It must be public if it is declared inside the interface but it can have any access modifier if declared within the class.
- Nested interfaces are declared static implicitly. Class JavaOuterClass{ interface JavaOuterInterface{
//code //code
interface JavaInnerInterface{ interface JavaInnerInterface{
//code //code
} }
} }
Note: to know what is the exception, put in the catch
Exception Handling: Exception class, and then make the error and it will
- When an error occurs, we use exception handling, so the appear in the console what type of exception it is.
exception is caught and processed.
- try {
// try block if there is an error then it will jump to catch.
} catch (ExceptionOne e) {
// catch block
} catch (ExceptionTwo e) {
// catch block
} finally {
// Code to be executed whether or not an exception is
thrown, usually u need this to close file or database.
}
- predefined exceptions:
- IOException
- NoSuchMethodException
- FileNotFoundException
- NumberFormatException
- DivisionByZeroException
- ArrayIndexOutOfBoundsException
Note: MyArrayList and MyLinkedList. These two classes have common operations, but different data fields.
Note: can choose either MyList as an interface or MyAbstractList as an abstract class to work with.
MyList
public interface MyList<E> extends java.lang.Iterable<E> {
/** Add a new element at the end of this list */
public void add(E e);
/** Return the element from this list at the specified index */
public E get(int index);
/** Return the index of the first matching element in this list.
* Return -1 if no match. */
public int indexOf(E e);
/** Return the index of the last matching element in this list
* Return -1 if no match. */
public int lastIndexOf(E e);
/** Remove the first occurrence of the element o from this list.
* Shift any subsequent elements to the left.
* Return true if the element is removed. */
public boolean remove(E e);
// Move the elements to the right after the specified index @Override /** Return the element at the specified index */
public E get(int index) {
for (int i = size - 1; i >= index; i--) checkIndex(index);
data[i + 1] = data[i]; return data[index];
}
// Insert new element to data[index]
private void checkIndex(int index) {
data[index] = e; if (index < 0 || index >= size)
throw new IndexOutOfBoundsException
// Increase size by 1 //("Index: " + index + ", Size: " + size);
("index " + index + " out of bounds");
size++; }
}
@Override /** Return the index of the first matching element @Override /** Replace the element at the specified position
* in this list. Return -1 if no match. */ * in this list with the specified element. */
public int indexOf(E e) {
public E set(int index, E e) {
for (int i = 0; i < size; i++)
if (e.equals(data[i])) return i; checkIndex(index);
E old = data[index];
return -1; data[index] = e;
} return old;
}
@Override /** Return the index of the last matching element
* in this list. Return -1 if no match. */
@Override
public int lastIndexOf(E e) {
for (int i = size - 1; i >= 0; i--) public String toString() {
if (e.equals(data[i])) return i; StringBuilder result = new StringBuilder("[");
return e;
}
@Override /** Override iterator() defined in Iterable */
public java.util.Iterator<E> iterator() {
return new ArrayListIterator();
}
@Override
public boolean hasNext() {
return (current < size);
}
@Override
public E next() {
return data[current++];
}
@Override
public void remove() {
MyArrayList.this.remove(current);
}
}
}
The code in the next slide
MyLinkedList
public class MyLinkedList<E> extends MyAbstractList<E> { /** Add an element to the beginning of the list */
private Node<E> head, tail; public void addFirst(E e) {
Node<E> newNode = new Node<E>(e); // Create a new node
/** Create a default list */ newNode.next = head; // link the new node with the head
public MyLinkedList() { } head = newNode; // head points to the new node
size++; // Increase list size
/** Create a list from an array of objects */
public MyLinkedList(E[] objects) { if (tail == null) // the new node is the only node in list
super(objects); tail = head;
} }
/** Return the head element in the list */ /** Add an element to the end of the list */
public E getFirst() { public void addLast(E e) {
if (size == 0) { Node<E> newNode = new Node<E>(e); // Create a new for element e
return null;
} if (tail == null) {
else { head = tail = newNode; // The new node is the only node in list
return head.element; }
} else {
} tail.next = newNode; // Link the new with the last node
tail = tail.next; // tail now points to the last node
/** Return the last element in the list */ }
public E getLast() {
if (size == 0) { size++; // Increase size
return null; }
}
else {
return tail.element;
}
}
@Override /** Add a new element at the specified index /** Remove the last node and
* in this list. The index of the head element is 0 */ * return the object that is contained in the removed node. */
public void add(int index, E e) { public E removeLast() {
if (index == 0) {
if (size == 0) {
addFirst(e);
} return null;
else if (index >= size) { }
addLast(e); else if (size == 1) {
} Node<E> temp = head;
else { head = tail = null;
Node<E> current = head; size = 0;
for (int i = 1; i < index; i++) {
return temp.element;
current = current.next;
} }
Node<E> temp = current.next; else {
current.next = new Node<E>(e); Node<E> current = head;
(current.next).next = temp;
size++; for (int i = 0; i < size - 2; i++) {
} current = current.next;
}
}
/** Remove the head node and
* return the object that is contained in the removed node. */ Node<E> temp = tail;
public E removeFirst() { tail = current;
if (size == 0) { tail.next = null;
return null; size--;
} return temp.element;
else {
}
Node<E> temp = head;
head = head.next; }
size--;
if (head == null) {
tail = null;
}
return temp.element;
}
}
@Override /** Remove the element at the specified position in this @Override /** Override toString() to return elements in the list */
* list. Return the element that was removed from the list. */ public String toString() {
public E remove(int index) { StringBuilder result = new StringBuilder("[");
if (index < 0 || index >= size) {
return null; Node<E> current = head;
} for (int i = 0; i < size; i++) {
else if (index == 0) { result.append(current.element);
return removeFirst(); current = current.next;
} if (current != null) {
else if (index == size - 1) { result.append(", "); // Separate two elements with a comma
return removeLast(); }
} else {
else { result.append("]"); // Insert the closing ] in the string
Node<E> previous = head; }
}
for (int i = 1; i < index; i++) {
previous = previous.next; return result.toString();
} }
@Override /** Return the index of the head matching element in private void checkIndex(int index) {
* this list. Return -1 if no match. */ if (index < 0 || index >= size)
public int indexOf(E e) { throw new IndexOutOfBoundsException
System.out.println("Implementation left as an exercise"); ("Index: " + index + ", Size: " + size);
return 0; }
}
@Override
public boolean hasNext() {
return (current != null);
}
@Override
public E next() {
E e = current.element;
current = current.next;
return e;
}
@Override
public void remove() {
System.out.println("Implementation left as an exercise");
}
}
System.out.println(current.element);
return true;
}
current = current.next;
}
}
return false;
}
Get
public E getMiddleValue(){
return get(size/2);
}
indexOf
public DoublyLinkedList() {
size = 0;
this.head=null;
this.tail=null;
}
public void addFirst(E element) {
//create object tmp and set pointer of the new node
Node<E> tmp = new Node(element, head, null);
//set head.prev of current head to be linked to the new node
if(head != null ) {head.prev = tmp;}
head = tmp; //now tmp become head
//if no tail, then tmp set to be a tail
if(tail == null) { tail = tmp;}
size++;//increase number of node
System.out.println("adding: "+element);
}
public void addLast(E element) {
//create object tmp and set pointer of the previous node
Node<E> tmp = new Node(element, null, tail);
//set tail.next point to object tmp
if(tail != null) {tail.next = tmp;}
//now tmp become tail
tail = tmp;
//if no head, then tmp set to be a head
if(head == null) { head = tmp;}
size++;//increase number of node
System.out.println("adding: "+element);
}
Code next slide
public void add(int index, E element){
//index can only be 0 ~ size()
if(index < 0 || index > size)
throw new IndexOutOfBoundsException();
if(index == 0)
addFirst(element);
else if(index == size)
addLast(element);
else{
/* set from head and begin traverse
stop on required position */
Node<E> temp = head;
for(int i=0; i<index; i++){
temp = temp.next;
}
/* create object insert and set pointer of the next pointer
to the temp node and also set pointer of the prev pointer
to the temp.prev node
*/
Node<E> insert = new Node(element, temp, temp.prev);
//set pointer 'next' of the node temp.prev to new node insert
temp.prev.next = insert;
//set pointer 'prev' of the node temp to new node insert
temp.prev = insert;
size ++;
}
}
Traversing Forward
public void iterateForward(){
System.out.println("iterating forward..");
Node<E> tmp = head;
while(tmp != null){
System.out.print(tmp.element);
System.out.print(" ");
tmp = tmp.next;
}
}
public E pop() {
if(isEmpty()) throw new java.util.EmptyStackException();
E o = list.get(getSize() - 1);
list.remove(getSize() - 1);
return o;
}
@Override
public String toString() { return "stack: " + list.toString();}
public static boolean isHTMLMatched(String html) {
Stack<String> buffer = new Stack<>( );
int j = html.indexOf('<'); // find first ’<’ character (if any)
while (j != -1) {
int k = html.indexOf('>', j+1); // find next ’>’ character
if (k == -1)
return false; // invalid tag
String tag = html.substring(j+1, k); // strip away < >
if (!tag.startsWith("/")) // this is an opening tag
buffer.push(tag);
else { // this is a closing tag
if (buffer.isEmpty( ))
return false; // no tag to match
if (!tag.substring(1).equals(buffer.pop( )))
return false; // mismatched tag
}
j = html.indexOf('<', k+1); // find next ’<’ character (if any)
}
return buffer.isEmpty( ); // were all opening tags matched?
}
Postfix Expressions
• Can be implemented using stacks
• Also called Reverse Polish Notation, is an alternative way of
representing mathematics expressions
• In a postfix evaluation format for an arithmetic expression, an
operator comes after its operands.
Errors
/** Evaluates a postfix expression.
@param postfix a string that is a valid postfix expression.
@return the value of the postfix expression. */
public static double evaluatePostfix(String postfix) {
GenericStack<Double> valueStack = new GenericStack<>();
String[] tokens = postfix.split(" ");
for (String token: tokens){
if(isNumeric(token))valueStack.push(Double.valueOf(token));
else if (token.equals("+") || token.equals("-") || token.equals("*") || token.equals("/") || token.equals("^")){
Double operandTwo = valueStack.pop();
Double operandOne = valueStack.pop();
Double result = compute(operandOne, operandTwo, token);
valueStack.push(result);
}
} // end for
return (valueStack.peek());
} // end evaluatePostfix
switch (operator) {
case "+":
result = operandOne + operandTwo;
break;
case "-":
result = operandOne - operandTwo;
break;
case "*":
result = operandOne * operandTwo;
break;
case "/":
result = operandOne / operandTwo;
break;
case "^":
result = Math.pow(operandOne, operandTwo);
break;
default: // Unexpected character
result = 0;
break;
} // end switch
return result;
} // end compute
Queue
public class Queue<E> {
private java.util.LinkedList<E> list = new java.util.LinkedList<>();
public void enqueue(E e) { list.addLast(e); }
public E dequeue() { return list.removeFirst(); }
public int getSize() { return list.size(); }
@Override
public String toString() { return "Queue: " + list.toString(); }
}
Priority Queue
- In a priority queue, elements are assigned with priorities. When accessing
elements, the element with the highest priority is removed first.
- A priority queue has a largest-in, first-out behavior (however you need to
double check whether the larger the higher the priority, or the smaller the
higher the priority).
- For example, the emergency room in a hospital assigns priority numbers to
patients; the patient with the highest priority is treated first. The assumption
here the higher the number the higher the priority.
- A priority queue is a collection in which all elements have a comparison
(priority) ordering.
- It provides only simple access and update operations where a deletion always
removes the element of highest priority
public class PriorityQueueDemo {
public static void main(String[] args) {
PriorityQueue<String> queue1 = new PriorityQueue<>();
queue1.offer("Oklahoma");
queue1.offer("Indiana");
queue1.offer("Georgia");
queue1.offer("Texas");
System.out.println("Priority queue using Comparable:");
while (queue1.size() > 0) System.out.print(queue1.poll() + " ");
Note: Implements the Comparator interface to use its compare method to arrange
the strings based on alphabetically ordaining.
public class Customer implements Comparable<Customer> {
private Integer id;
private String name;
public Customer(Integer id, String name) { this.id = id; this.name = name; }
public Integer getID() { return id; }
public String getName() { return name; }
@Override
public int compareTo(Customer c) { return this.getID().compareTo(c.getID()); }
@Override
public String toString() { return "Customer [ id=" + id + ", name=" + name + " ]" ; }
}
} //end class
Graph
Notes:
public Vertex() {
vertexInfo=null;
indeg=0;
outdeg=0;
nextVertex = null;
firstEdge = null;
}
Vertex<T,N> head;
//no need for a tail.
int size;
public Graph(){
head=null;
size=0;
}
vertex1_temp.outdeg++;
vertex1_temp.indeg++;
vertex2_temp.outdeg++;
vertex2_temp.indeg++;
return true;
}
vertex2_temp=vertex2_temp.nextVertex;
}
}
vertex1_temp=vertex1_temp.nextVertex;
}
return false;
}
public boolean addEdge(T source, T destination, N w) {
if (head==null)
return false;
if (!hasVertex(source) || !hasVertex(destination))
return false;
Vertex<T,N> sourceVertex = head;
while (sourceVertex!=null) {
if ( sourceVertex.vertexInfo.compareTo( source ) == 0 ) { //means the same
// Reached source vertex, look for destination now
Vertex<T,N> destinationVertex = head;
while (destinationVertex!=null) {
if ( destinationVertex.vertexInfo.compareTo( destination ) == 0 ) {
// Reached destination vertex, add edge here
Edge<T,N> currentEdge = sourceVertex.firstEdge;
Edge<T,N> newEdge = new Edge<>(destinationVertex, w, currentEdge); //create the edge, the
reference of the another edge, will point to the old first edge.
sourceVertex.firstEdge=newEdge; //the new first edge will be the new one.
sourceVertex.outdeg++;
destinationVertex.indeg++;
return true;
}
destinationVertex=destinationVertex.nextVertex;
}
}
sourceVertex=sourceVertex.nextVertex;
}
return false;
}
public boolean hasEdge(T source, T destination){
if (head==null)
return false;
if (!hasVertex(source) || !hasVertex(destination))
return false; //if there the vertexes not exist in the destination or the source.
Vertex<T,N> sourceVertex = head;
while (sourceVertex!=null) {
if ( sourceVertex.vertexInfo.compareTo( source ) == 0 ) { //if found the source vertex
// Reached source vertex, look for destination now
Edge<T,N> currentEdge = sourceVertex.firstEdge;
while (currentEdge != null) { //look for destination vertex
if (currentEdge.toVertex.vertexInfo.compareTo(destination)==0)
// destination vertex found
return true;
currentEdge=currentEdge.nextEdge;
}
}
sourceVertex=sourceVertex.nextVertex;
}
return false;
}
public N getEdgeWeight(T source, T destination) {
N notFound=null;
if (head==null)
return notFound;
if (!hasVertex(source) || !hasVertex(destination))
return notFound;
Vertex<T,N> sourceVertex = head;
while (sourceVertex!=null) {
if ( sourceVertex.vertexInfo.compareTo( source ) == 0 ) {
// Reached source vertex, look for destination now
Edge<T,N> currentEdge = sourceVertex.firstEdge;
while (currentEdge != null) {
if (currentEdge.toVertex.vertexInfo.compareTo(destination)==0)
// destination vertex found
return currentEdge.weight;
currentEdge=currentEdge.nextEdge;
}
}
sourceVertex=sourceVertex.nextVertex;
}
return notFound;
}
public ArrayList<T> getNeighbours (T v) {
if (!hasVertex(v))
return null;
ArrayList<T> list = new ArrayList<T>();
Vertex<T,N> temp = head;
while (temp!=null) {
if ( temp.vertexInfo.compareTo( v ) == 0 ) {
// Reached vertex, look for destination now
Edge<T,N> currentEdge = temp.firstEdge;
while (currentEdge != null) {
list.add(currentEdge.toVertex.vertexInfo);
currentEdge=currentEdge.nextEdge;
}
}
temp=temp.nextVertex;
}
return list;
}
while (!hold.isEmpty()){
visited_list.add(hold.pop()); //add top of the stack to the list
Edge<T,N> firstNeighbor = visited_list.get(visited_list.size()-1).firstEdge;
ArrayList<Vertex<T,N>> neighbors = new ArrayList<>(); //to hold the neighbors of each vertex
while (firstNeighbor!=null){ //if it has neighbors, then add them to neighbors arraylist
neighbors.add(firstNeighbor.toVertex);
firstNeighbor=firstNeighbor.nextEdge;
}
for(int x=0;x<neighbors.size();x++)//check if the neighbor not already in the visited list then add it to the stack
if(!visited_list.contains(neighbors.get(x))) hold.push(neighbors.get(x));
} //end while
for(int x=0;x<visited_list.size();x++){ //to get the vertices info
list.add(visited_list.get(x).vertexInfo);
}
return list;
//note: u can check if the search complete by checking if visited_list.size()==graph.getSize(), then it is completed
} //end method
public static void main(String[] args) {
Ready.Graph<String, Integer> graph1 = new Graph<>();
String[] cities = {"Alor Setar", "Kuching", "Langkawi", "Melaka", "Penang", "Tawau"};
for (String i : cities)
graph1.addVertex(i);
System.out.println("In and out degree for Kuching is " + graph1.getIndeg("Kuching") + " and " + graph1.getOutdeg("Kuching") );
System.out.println("In and out degree for Penang is " + graph1.getIndeg("Penang") + " and " + graph1.getOutdeg("Penang") );
System.out.println("In and out degree for Ipoh is " + graph1.getIndeg("Ipoh") + " and " + graph1.getOutdeg("Ipoh") );
System.out.println();
graph1.removeVertex("Kuching");
System.out.println("\nPrint Edges : " );
graph1.printEdges();
}
Graph Traversals (Graph Search):
-The process of visiting (checking and/or updating) each vertex in a graph.
-Both traversals result in a spanning tree, which can be modeled using a class.
Two methods:
1- Depth-First Search:
- The search can start at any vertex.
- Algorithm:
1. Start by putting any one of the graph's vertices on top of a stack.
2. Take the top item of the stack and add it to the visited list.
3. Create a list of that vertex's adjacent nodes. Add the ones which aren't in the
visited list to the top of the stack.
4. Keep repeating steps 2 and 3 until the stack is empty.
level. First the root is visited, then all the children of the root, then the
grandchildren of the root from left to right, and so on.
Breadth-First Search
● Algorithm:
1. Start by putting any one of the graph's vertices at the back of a queue.
2. Take the front item of the queue and add it to the visited list.
3. Create a list of that vertex's adjacent nodes. Add the ones which aren't in the visited list to the back
of the queue.
4. Keep repeating steps 2 and 3 until the queue is empty.
2 3
Trace Recursive factorial
import java.util.Scanner;
// Display factorial
System.out.println("Factorial of " + n + " is " + factorial(n));
}
How do you find fib(index) for a given index? It is easy to find fib(2), because you know fib(0) and
fib(1). Assuming that you know fib(index - 2) and fib(index - 1), you can obtain fib(index) immediately.
Thus, the problem of computing fib(index) is reduced to computing fib(index - 2) and fib(index - 1).
When doing so, apply the idea recursively until index is reduced to 0 or 1.
The base case is index = 0 or index = 1. If you call the method with index = 0 or index = 1, it
immediately returns the result. If you call the method with index >= 2, it divides the problem into two
subproblems for computing fib(index - 1) and fib(index - 2) using recursive calls.
What happens if a recursive method never reaches a base case?
• Infinite recursion - occurs if recursion does not reduce the problem in a manner that allows it to eventually converge into
the base case
• The stack will never stop growing.
• But OS limits the stack to a particular height, so that no program eats up too much memory.
• If a program's stack exceeds this size, the computer initiates an exception (StackOverflowError), which typically would
crash the program.
Recursion Iteration
– Terminate when a base case is reached – Terminates when a condition is proven to be false
– Each recursive call requires extra space on the – Each iteration does not require any extra space
stack frame (memory) – An infinite loop could loop forever since there is
– If we get infinite recursion, it may result in stack no extra memory being created
overflow
Directory (folder) Size
• A problem that is difficult to solve without using recursion.
• The size of a directory is the sum of the sizes of all files in the directory.
• A directory may contain subdirectories.
- The size of the directory can be defined recursively as follows:
import java.io.File;
import java.util.Scanner;
if (file.isDirectory()) {
File[] files = file.listFiles(); // All files and subdirectories
for (int i = 0; files != null && i < files.length; i++) {
size += getSize(files[i]); // Recursive call
}
}
else { // Base case
size += file.length(); //if it is a file not a folder
}
return size;
}
}
Searching
Searching: locating a particular element value in the array. The common searching techniques
are Linear Search and Binary Search.
Linear search: This method works well for small arrays or for unsorted arrays. will search the
array one by one, so you use for loop.
- continues to do so until the key matches an element in the list or the list is exhausted without a match being
found.
- If found, returns the index of the element in the array that matches the key.
- If no match is found, the search returns -1.
Other way
if (array.length <= 1) return array; //base case
else
result[resultPointer++] = right[rightPointer++];
}
that A is O(n).
• In general, each node in a tree can have an arbitrary number of children. We
sometimes call such a tree a general tree. If each node has no more than n
children, the tree is called an n-ary tree.
• Not every general tree is an n-ary tree. If each node has at most two children,
the tree is called a binary tree.
Binary tree: is a hierarchical structure. It is either empty or consists of
an element, called the root, and two distinct binary trees, called the
left subtree and right subtree, either or both of which may be empty.
- Each node in a binary tree has zero, one, or two subtrees.
Terms:
• Length of path – number of edges in the path (eg:60-45 → 2)
• Depth – length of path from root to node (eg:60 → 0; 55→1)
• Level – set of all nodes at a given depth (e.g:55,100)
• Siblings – nodes share same parent node (eg: 45-57)
• Left child- root of the left subtree of a node
• Leaf – node without children (eg: A)
• Height – length of path fr root node to its furthest leaf (e.g 2)
Binary Search Tree
- A special type of binary tree called a binary search tree.
- It has no duplicate elements.
- The value in the left < the node < the value in the right.
- Representing Binary Trees:
A binary tree can be represented using a set of linked nodes. Each node contains a value and
two links named left and right that reference the left child and right child, respectively as
shown below.
- Create node:
• Variable root refers to the root node of the tree.
• If tree is empty, root is null.
• Create root node:
TreeNode<Integer> root = new TreeNode<Integer>(new Integer(60));
• Create left child node:
root.left = new TreeNode<Integer>(new Integer(55));
• Create right child node:
root.right = new TreeNode<Integer>(new Integer(100));
The Tree Interface
public interface Tree<E> extends Iterable<E> {
/** Return true if the element is in the tree */
public boolean search(E e);
• Postorder: visit the left subtree of the current node first, then the
right subtree of the current node, and finally the current node itself.
• Breadth-first (level-order): visit the nodes level by level. First visit the root,
then all children of the root from left to right, then grandchildren of the root from
left to right, and so on.
For example, in the tree above,
the inorder is 45 55 57 59 60 67 100 101 107.
the postorder is 45 59 57 55 67 101 107 100 60.
the preorder is 60 55 45 57 59 100 67 107 101.
the breadth-first traversal is 60 55 100 45 57 67 107 59 101.
Deleting Elements in a Binary Search Tree
• Need to first locate the node that contains the element and also its parent
node.
• Let current point to the node that contains the element in the binary tree and
parent point to the parent of the current node.
• The current node may be a left child or a right child of the parent node.
There are two cases to consider:
Case 1: The current node does not have a left child, as shown in this figure (a).
Simply connect the parent with the right child of the current node, as shown in
this figure (b).
Case 2: The current node has a left child.
• Let rightMost point to the node that contains the largest element in the left subtree of the
current node and parentOfRightMost point to the parent node of the rightMost node, as
shown in next figure part (a).
• Note that the rightMost node cannot have a right child, but may have a left child.
• Replace the element value in the current node withn the one in the rightMost node,
connect the parentOfRightMost node with the left child of the rightMost node, and delete
the rightMost node, as shown in next figure part (b).
public class BST<E extends Comparable<E>>{
/** Returns a path from the root leading to the specified element */
public java.util.ArrayList<TreeNode<E>> path(E e) {
java.util.ArrayList<TreeNode<E>> list = new java.util.ArrayList<TreeNode<E>>();
TreeNode<E> current = root; // Start from the root
while (current != null) {
list.add(current); // Add the node to the list
if (e.compareTo(current.element) < 0) current = current.left;
else if (e.compareTo(current.element) > 0) current = current.right;
else break;
} //end while
return list; // Return an array list of nodes
}
// Insert element into the binary tree Return true if the element is inserted successfully.
public boolean insert(E element) {
if (root == null) root = new TreeNode<E>(element); //if the tree is empty, then create a new root
else { // locate the parent node
TreeNode<E> parent = null;
TreeNode<E> current = root;
while (current != null) {
if (element.compareTo(current.element) < 0) { //less then go left
parent = current;
current = current.left;
} else if (element.compareTo(current.element) > 0) { //bigger then go right
parent = current;
current = current.right;
} else return false; // Duplicate node not inserted
} //end while
//now add the node:
if(element.compareTo(parent.element)<0)parent.left =new TreeNode<E>(element);//if element is less than the parent.
else parent.right = new TreeNode<E>(element); //if element is bigger than parent.
} //end else
size++;
return true; // Element inserted successfully
}
/** Returns the height of the tree*/
public int height(){ return height(root); }
/** Returns the height of the tree from giving node*/
private int height(TreeNode<E> node){
if (node == null) return -1;
return 1 + Math.max(height(node.left), height(node.right));
}
size--;
return true; // Element deleted successfully
} //end delete
/** Obtain an iterator. Use inorder. */
public java.util.Iterator<E> iterator() { return new InorderIterator(); }
}
public static void main(String[] args) {
// Create a BST
BST<String> tree = new BST<String>();
tree.insert("George");
tree.insert("Michael");
tree.insert("Tom");
tree.insert("Adam");
tree.insert("Jones");
tree.insert("Peter");
tree.insert("Daniel");
// Traverse tree
System.out.print("Inorder (sorted): ");
tree.inorder();
System.out.print("\nPostorder: ");
tree.postorder();
System.out.print("\nPreorder: ");
tree.preorder();
System.out.print("\nThe number of nodes is " + tree.getSize());
switch (l){
case LOW -> System.out.println("It is low"); //print this
case MEDIUM -> System.out.println("It is medium");
case HIGH -> System.out.println("It is High");
}
} //class ends
HashMap
HashMap: list of keys and for each key there is a value.
- Hashmap can be raw type or it can have <Key_Type,Value_Type>.
- HashMaps do not have an order.
- Methods:
- put(key,value);
- get(key);
- remove(key);
- containsValue(value);
- containsKey(key);
- size();
- replace(key,newValue);
- values(); //print the values.
- ketSet(); //print the keys.
- User-defined interface with a method with a parameter: - User-defined interface with a method with two parameters:
@FunctionalInterface @FunctionalInterface
public interface MyInterface { //user-defined a functional interface public interface MyInterface { //user-defined a functional interface
public void message(String name); public void message(String name, char symbol);
} }
MyFrame(){
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(420,420);
this.setLayout(null);
this.setVisible(true);
myButton.setBounds(100,100,200,100);
this.add(myButton);
//before:
/*
myButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("U clicked the button!");
}
});
*/
//Using lambda expression, because ActionListener interface has only one abstract method
myButton.addActionListener((e) -> System.out.println("U clicked the button!"));
1- Static method
- Syntax: (ClassName::methodName)
2-Instance method
- Syntax: (objectOfClass::methodName)
3- Super method
- Syntax: (super::methodName)
4- Class Constructor
Syntax: (ClassName::new)
How to add an External library to the project in IntelliJ:
1. Download the library as jar file.
2. Click File from the toolbar.
3. Select Project Structure option (CTRL + SHIFT + ALT + S (shortcut on
Windows)).
4. Select Modules at the left panel.
5. Select Dependencies tab.
6. Select + icon.
7. Select 1 JARs or directories option.