INFO404 Reference
INFO404 Reference
md 2024-02-06
INFO404 Notes
by Hassan Maouch
General Notes:
String Methods:
String.indexOf(“char”,nb); => returns the index of the nth repetitive char (indexing starts from 0)
String.split(“char+”)[nb]; => (indexing starts from 0) returns the rest of the word after the nth
repetitive char
String.split(“char”)[0]; => returns from the beginning of the word till the first occurrence of char
To prevent inheritance use “final” this ensures no changes in the subclass (the class & methods)
Abstract classes: no implementations in the abstract method of the abstract class, subclasses of abstract
superclass must implement abstract methods
Reflection: is the ability to find out more about classes and their properties in a running program
Generics type: E (elements), K & V(key and value), T,U,S & W for all types
Wildcard / the Joker “?”
Bounded: Set/List/.. < ? extends className >, List < ? super className >
Unbounded: without super or extends
Collections:
1 / 27
NotesHassan.md 2024-02-06
Equal methods:
1. Check reference
2. Check if is not null
3. Check if they are the same type
4. Compare attributes
Super class:
Subclass:
2 / 27
NotesHassan.md 2024-02-06
Shallow Clone:
Deep Clone: Same as shallow clone in implementing and access modifier and throwing plus clone also the
mutable objects then return // mutable = changeable
Collections
Interface Collection<E>
boolean add(E e): Ensures that this collection contains the specified element (optional operation).
Iterator<E> iterator(): Returns an iterator over the elements in this collection.
Interface Iterator<E>
Default methods:
void forEachRemaining(Consumer<? super E> action): Performs the given action for each
remaining element until all elements have been processed or the action throws an exception.
boolean hasNext(): Returns true if the iteration has more elements.
E next(): Returns the next element in the iteration.
3 / 27
NotesHassan.md 2024-02-06
default void remove(): Removes from the underlying collection the last element returned by this
iterator (optional operation).
Interface Iterable<T>
Default method:
default void forEach(Consumer<? super T> action): Performs the given action for each
element of the Iterable until all elements have been processed or the action throws an exception.
Iterator<T> iterator(): Returns an iterator over elements of type T.
Class AbstractCollection<E>
Abstract method:
abstract Iterator<E> iterator(): Returns an iterator over the elements contained in this
collection.
Interface ListIterator<E>
void add(E e): Inserts the specified element into the list (optional operation).
boolean hasNext(): Returns true if this list iterator has more elements when traversing the list in the
forward direction.
boolean hasPrevious(): Returns true if this list iterator has more elements when traversing the list in
the reverse direction.
E next(): Returns the next element in the list and advances the cursor position.
int nextIndex(): Returns the index of the element that would be returned by a subsequent call to
next().
E previous(): Returns the previous element in the list and moves the cursor position backwards.
int previousIndex(): Returns the index of the element that would be returned by a subsequent call
to previous().
4 / 27
NotesHassan.md 2024-02-06
void remove(): Removes from the list the last element that was returned by next() or previous()
(optional operation).
void set(E e): Replaces the last element returned by next() or previous() with the specified element
(optional operation).
Interface List<E>
An ordered collection (also known as a sequence) Unlike sets, lists typically allow duplicate elements.
Class LinkedList<E>
Doubly-linked list implementation of the List and Deque interfaces. Implements all optional list operations,
and permits all elements (including null).
Constructors:
Class ArrayList<E>
Resizable-array implementation of the List interface. Implements all optional list operations, and permits all
elements, including null.
Constructors:
Interface Set<E>
5 / 27
NotesHassan.md 2024-02-06
Class HashSet<E>
This class implements the Set interface, backed by a hash table (actually a HashMap instance). It makes no
guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain
constant over time. This class permits the null element.
Constructors:
HashSet(): Constructs a new, empty set; the backing HashMap instance has default initial capacity (16)
and load factor (0.75).
HashSet(int initialCapacity): Constructs a new, empty set; the backing HashMap instance has
the specified initial capacity and default load factor (0.75).
HashSet(int initialCapacity, float loadFactor): Constructs a new, empty set; the backing
HashMap instance has the specified initial capacity and the specified load factor.
HashSet(Collection<? extends E> c): Constructs a new set containing the elements in the
specified collection.
Class TreeSet<E>
The elements are ordered using their natural ordering, or by a Comparator provided at set creation time,
depending on which constructor is used.
Constructors:
TreeSet(): Constructs a new, empty tree set, sorted according to the natural ordering of its elements.
TreeSet(Collection<? extends E> c): Constructs a new tree set containing the elements in the
specified collection, sorted according to the natural ordering of its elements.
TreeSet(Comparator<? super E> comparator): Constructs a new, empty tree set, sorted according
to the specified comparator.
TreeSet(SortedSet<E> s): Constructs a new tree set containing the same elements and using the
same ordering as the specified sorted set.
Interface Queue<E>
6 / 27
NotesHassan.md 2024-02-06
Interface Deque<E>
A linear collection that supports element insertion and removal at both ends.
Class PriorityQueue<E>
An unbounded priority queue based on a priority heap. The elements of the priority queue are ordered
according to their natural ordering, or by a Comparator provided at queue construction time, depending on
which constructor is used. A priority queue does not permit null elements. A priority queue relying on natural
ordering also does not permit insertion of non-comparable objects (doing so may result in
ClassCastException).
Interface Map<K,V>
An object that maps keys to values. A map cannot contain duplicate keys; each key can map to at most one
value.
Nested Classes:
Important Methods:
void clear(): Removes all of the mappings from this map (optional operation).
boolean containsKey(Object key): Returns true if this map contains a mapping for the specified
key.
boolean containsValue(Object value): Returns true if this map maps one or more keys to the
specified value.
Set<Map.Entry<K,V>> entrySet(): Returns a Set view of the mappings contained in this map.
V get(Object key): Returns the value to which the specified key is mapped, or null if this map
contains no mapping for the key.
7 / 27
NotesHassan.md 2024-02-06
int hashCode(): Returns the hash code value for this map.
boolean isEmpty(): Returns true if this map contains no key-value mappings.
Set<K> keySet(): Returns a Set view of the keys contained in this map.
V put(K key, V value): Associates the specified value with the specified key in this map (optional
operation).
void putAll(Map<? extends K, ? extends V> m): Copies all of the mappings from the specified
map to this map (optional operation).
V remove(Object key): Removes the mapping for a key from this map if it is present (optional
operation).
int size(): Returns the number of key-value mappings in this map.
Collection<V> values(): Returns a Collection view of the values contained in this map.
Get the old value associated with a key + update it + put back.
Example:
This works except in the case when the word is encountered for the first time, get() returns null, and a
NullPointerException occurs. To remedy this, use getOrDefault method:
8 / 27
NotesHassan.md 2024-02-06
remove(): removes key and its associated value from the map However, cannot add an element to key
set view. It makes no sense to add a key without also adding a value.
Entry set view has the same restriction even though it would make conceptual sense to add a new
key/value pair.
Class TreeMap<K,V>
A Red-Black tree based NavigableMap implementation. The map is sorted according to the natural ordering
of its keys, or by a Comparator provided at map creation time, depending on which constructor is used.
Constructors:
TreeMap(): Constructs a new, empty tree map, using the natural ordering of its keys.
TreeMap(Comparator<? super K> comparator): Constructs a new, empty tree map, ordered
according to the given comparator.
TreeMap(Map<? extends K, ? extends V> m): Constructs a new tree map containing the same
mappings as the given map, ordered according to the natural ordering of its keys.
TreeMap(SortedMap<K, ? extends V> m): Constructs a new tree map containing the same
mappings and using the same ordering as the specified sorted map.
Class HashMap<K,V>
Hash table based implementation of the Map interface. This implementation provides all of the optional map
operations, and permits null values and the null key.
Constructors:
HashMap(): Constructs an empty HashMap with the default initial capacity (16) and the default load
factor (0.75).
HashMap(int initialCapacity): Constructs an empty HashMap with the specified initial capacity
and the default load factor (0.75).
HashMap(int initialCapacity, float loadFactor): Constructs an empty HashMap with the
specified initial capacity and load factor.
HashMap(Map<? extends K, ? extends V> m): Constructs a new HashMap with the same mappings
as the specified Map.
9 / 27
NotesHassan.md 2024-02-06
Lambda expressions in Java provide a concise way to represent anonymous functions, making code more
readable and expressive. They are commonly used in functional-style programming and in passing behavior
as arguments to methods.
Syntax:
Examples:
Lambda expressions are often used with the Comparator interface for sorting collections in a more concise
and expressive manner.
The Stream API in Java provides a powerful way to process collections of objects in a functional-style manner.
It allows for operations like filtering, mapping, reducing, and sorting on collections with ease.
Example:
10 / 27
NotesHassan.md 2024-02-06
.filter(n -> n % 2 == 0)
.collect(Collectors.toList());
The Stream API provides convenient methods for sorting collections using lambda expressions.
By leveraging lambda expressions and the Stream API, Java developers can write more concise and readable
code for processing collections, making code maintenance and understanding easier.
In Java, the Comparable and Comparator interfaces provide mechanisms for sorting collections of objects
based on their natural ordering or custom sorting criteria.
Comparable Interface
The Comparable interface allows objects to define their natural ordering by implementing the compareTo
method. This interface is typically implemented by the class whose instances need to be sorted.
Example:
Suppose we have a Person class with a name field. We want to sort a collection of Person objects
alphabetically based on their names.
11 / 27
NotesHassan.md 2024-02-06
this.name = name;
}
In this example, the compareTo method compares Person objects based on their names.
Comparator Interface
The Comparator interface provides a way to define custom sorting logic separately from the class being
sorted. It allows for more flexible sorting, especially when dealing with classes that do not implement
Comparable or when multiple sorting criteria are needed.
Example:
Suppose we have a Student class with name and age fields. We want to sort a collection of Student objects
first by age and then by name.
import java.util.Comparator;
Sorting Collections
When sorting collections, objects can be sorted either using their natural ordering (if they implement
Comparable) or using a custom Comparator.
12 / 27
NotesHassan.md 2024-02-06
Design Patterns
Creational Patterns
Singleton Pattern
Example: Logger class ensuring only one instance is used throughout the application.
private Logger() {
}
// Product interface
public interface Vehicle {
void drive();
}
// Concrete Products
public class Car implements Vehicle {
@Override
public void drive() {
System.out.println("Driving a car");
13 / 27
NotesHassan.md 2024-02-06
}
}
// Creator
public abstract class VehicleFactory {
public abstract Vehicle createVehicle();
}
// Concrete Creator
public class CarFactory extends VehicleFactory {
@Override
public Vehicle createVehicle() {
return new Car();
}
}
// Abstract Product A
public interface Engine {
void producePower();
}
// Concrete Product A
public class GasolineEngine implements Engine {
@Override
public void producePower() {
System.out.println("Producing power with gasoline engine");
}
}
// Abstract Product B
public interface Wheel {
void rotate();
}
14 / 27
NotesHassan.md 2024-02-06
// Concrete Product B
public class RubberWheel implements Wheel {
@Override
public void rotate() {
System.out.println("Rubber wheel rotating");
}
}
// Abstract Factory
public interface VehicleFactory {
Engine createEngine();
Wheel createWheel();
}
// Concrete Factory
public class CarFactory implements VehicleFactory {
@Override
public Engine createEngine() {
return new GasolineEngine();
}
@Override
public Wheel createWheel() {
return new RubberWheel();
}
}
Prototype Pattern
// Prototype
public abstract class Animal implements Cloneable {
protected String name;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
// Concrete Prototypes
public class Dog extends Animal {
public Dog() {
this.name = "Dog";
}
@Override
15 / 27
NotesHassan.md 2024-02-06
@Override
public void makeSound() {
System.out.println("Meow!");
}
}
Structural Patterns
Adapter Pattern
// Target interface
public interface EnglishSpeaker {
void speakEnglish();
}
// Adaptee
public class FrenchSpeaker {
public void parlerFrancais() {
System.out.println("Parler en Français");
}
}
// Adapter
public class FrenchTranslator implements EnglishSpeaker {
private FrenchSpeaker speaker;
@Override
public void speakEnglish() {
speaker.parlerFrancais();
}
}
Composite Pattern
16 / 27
NotesHassan.md 2024-02-06
Example: A company's organizational structure where departments contain employees and sub-departments.
// Component interface
public interface Department {
void showDepartmentDetails();
}
// Leaf
public class Employee implements Department {
private String name;
@Override
public void showDepartmentDetails() {
System.out.println("Employee: " + name);
}
}
// Composite
public class DepartmentComposite implements Department {
private List<Department> departments = new ArrayList<>();
@Override
public void showDepartmentDetails() {
for (Department department : departments) {
department.showDepartmentDetails();
}
}
}
Bridge Pattern
// Abstraction
public abstract class Shape {
protected DrawingAPI drawingAPI;
17 / 27
NotesHassan.md 2024-02-06
this.drawingAPI = drawingAPI;
}
// Implementor
public interface DrawingAPI {
void drawCircle(double x, double y, double radius);
}
// Concrete Implementor
public class DrawingAPI1 implements DrawingAPI {
@Override
public void drawCircle(double x, double y, double radius) {
System.out.printf("API1.circle at %f:%f radius %f%n", x, y, radius);
}
}
// Concrete Implementor
public class DrawingAPI2 implements DrawingAPI {
@Override
public void drawCircle(double x, double y, double radius) {
System.out.printf("API2.circle at %f:%f radius %f%n", x, y, radius);
}
}
// Refined Abstraction
public class CircleShape extends Shape {
private double x, y, radius;
@Override
public void draw() {
drawingAPI.drawCircle(x, y, radius);
}
}
Flyweight Pattern
// Flyweight interface
public interface TextCharacter {
void draw(int fontSize);
18 / 27
NotesHassan.md 2024-02-06
// Concrete Flyweight
public class EnglishCharacter implements TextCharacter {
private char character;
@Override
public void draw(int fontSize) {
System.out.println("Drawing English character: " + character + " with font
size " + fontSize);
}
}
// Flyweight Factory
public class TextCharacterFactory {
private Map<Character, TextCharacter> characters = new HashMap<>();
Proxy Pattern
// Subject interface
public interface SensitiveData {
void access();
}
// Real Subject
public class SensitiveDataImpl implements SensitiveData {
@Override
public void access() {
System.out.println("Accessing sensitive data");
}
}
// Proxy
public class Proxy implements SensitiveData {
private SensitiveData realSubject;
private String password;
19 / 27
NotesHassan.md 2024-02-06
@Override
public void access() {
if (password.equals("correctPassword")) {
realSubject.access();
} else {
System.out.println("Access denied");
}
}
}
Decorator Pattern
// Component interface
public interface Pizza {
String getDescription();
double getCost();
}
// Concrete Component
public class PlainPizza implements Pizza {
@Override
public String getDescription() {
return "Plain Pizza";
}
@Override
public double getCost() {
return
5.0;
}
}
// Decorator
public abstract class PizzaDecorator implements Pizza {
protected Pizza pizza;
@Override
public String getDescription() {
return pizza.getDescription();
}
20 / 27
NotesHassan.md 2024-02-06
@Override
public double getCost() {
return pizza.getCost();
}
}
// Concrete Decorator
public class CheeseDecorator extends PizzaDecorator {
public CheeseDecorator(Pizza pizza) {
super(pizza);
}
@Override
public String getDescription() {
return pizza.getDescription() + ", Cheese";
}
@Override
public double getCost() {
return pizza.getCost() + 1.5;
}
}
Facade Pattern
Example: Complex process of booking a flight simplified into a single method call.
// Facade
public class FlightBookingFacade {
private HotelBooking hotelBooking;
private FlightBooking flightBooking;
public FlightBookingFacade() {
this.hotelBooking = new HotelBooking();
this.flightBooking = new FlightBooking();
}
Behavioral Patterns
Iterator Pattern
Example: Iterating over a collection of items without exposing its underlying representation.
21 / 27
NotesHassan.md 2024-02-06
// Aggregate interface
public interface Collection<T> {
Iterator<T> iterator();
}
// Concrete Aggregate
public class MyCollection<T> implements Collection<T> {
private List<T> items;
public MyCollection() {
this.items = new ArrayList<>();
}
@Override
public Iterator<T> iterator() {
return new MyIterator<>(items);
}
}
// Iterator interface
public interface Iterator<T> {
boolean hasNext();
T next();
}
// Concrete Iterator
public class MyIterator<T> implements Iterator<T> {
private List<T> items;
private int position;
@Override
public boolean hasNext() {
return position < items.size();
}
@Override
public T next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return items.get(position++);
}
}
22 / 27
NotesHassan.md 2024-02-06
Observer Pattern
// Observer interface
public interface Observer {
void update();
}
// Subject
public class Button {
private List<Observer> observers = new ArrayList<>();
// Concrete Observer
public class ButtonClickListener implements Observer {
@Override
public void update() {
System.out.println("Button clicked!");
}
}
Mediator Pattern
// Mediator
public interface ChatMediator {
void sendMessage(User user, String message);
}
// Concrete Mediator
public class ChatServer implements ChatMediator {
@Override
public void sendMessage(User user, String message) {
23 / 27
NotesHassan.md 2024-02-06
// Colleague
public class User {
private ChatMediator mediator;
private String name;
State Pattern
Example: Traffic light system changing behavior based on its current state.
// State interface
public interface TrafficLightState {
void change(TrafficLight light);
}
// Concrete States
public class RedLight implements TrafficLightState {
@Override
public void change(TrafficLight light) {
light.setState(new GreenLight());
}
}
// Context
24 / 27
NotesHassan.md 2024-02-06
public TrafficLight() {
this.state = new RedLight();
}
Strategy Pattern
// Strategy interface
public interface SortingStrategy<T extends Comparable<T>> {
void sort(List<T> items);
}
// Concrete Strategies
public class BubbleSort<T extends Comparable<T>> implements SortingStrategy<T> {
@Override
public void sort(List<T> items) {
// Bubble sort implementation
}
}
// Context
public class Sorter<T extends Comparable<T>> {
private SortingStrategy<T> strategy;
25 / 27
NotesHassan.md 2024-02-06
Memento Pattern
// Memento
public class Memento {
private String state;
// Originator
public class TextEditor {
private String text;
// Caretaker
public class TextEditorHistory {
private Stack<Memento> history = new Stack<>();
26 / 27
NotesHassan.md 2024-02-06
}
}
27 / 27
Design Patterns Cheat Sheet
Creational Patterns Structural Patterns (cont’d)
Abstract Factory Bridge
Provides an interface for creating families of related or dependent objects without Decouples an abstraction from its implementation so that the two can vary
specifying their concrete classes independently
Abstraction
AbstractFactory ConcreteFactory Client
+Operation()
+CreateProductA() +CreateProductA()
+CreateProductB() +CreateProductB() ConcreteImplementorA
creates
Client +OperationImpl()
Implementor
ProductA
AbstractProduct +OperationImpl() ConcreteImplementorB
ProductB +OperationImpl()
Builder
Composite
Separates the construction of a complex object from its representation so that the
same construction process can create different representations. Composes objects into tree structures to represent part-whole hierarchies
Composite
Director Builder
+Operation()
+Construct() +BuildPart() +Add(component)
Component
+Remove(component)
+Operation() +GetChild(index)
Client +Add(component)
Product builds ConcreteBuilder +Remove(component)
+GetChild(index) Leaf
+BuildPart()
+Operation()
Factory Method
Decorator
Defines an interface for creating an object but let subclasses decide which class to
instantiate Attaches additional responsibilities to an object dynamically
Prototype Facade
Specifies the kinds of objects to create using a prototypical instance and create new Provides a unified interface to a set of interfaces in a subsystem
objects by copying this prototype
Facade
ConcretePrototype1
+Clone()
Prototype
Client
+Clone() Subsystem
ConcretePrototype2
+Clone()
Flyweight
Ensure a class only has one instance and provide a global point of access to it
FlyweightFactory
Client
+GetFlyweight(key)
Singleton
-instance UnsharedFlyweight
+Operation(state)
-Singleton() Flyweight
+GetInstance()
+Operation(state)
Flyweight
+Operation(state)
Structural Patterns
Adapter
Proxy
Converts the interface of a class into another interface clients expect
Provides a surrogate or placeholder for another object to control access to it
Target Proxy
Client
+Request() +Request()
Subject
Client
+Request()
Adapter Adaptee RealSubject
+Request() +SpecificRequest() +Request()
Design Patterns Cheat Sheet
Behavioral Patterns Behavioral Patterns (cont’d)
Chain of Responsibility Observer
Avoids coupling the sender of a request to its receiver by giving more than one object Defines a one-to-many dependency between objects so that when one object changes
a chance to handle the request state all its dependents are notified and updated automatically
ConcreteHandler1 Subject
Observer
+HandleRequest() +Attach(observer)
Handler +Detach(observer) +Update()
Client +Notify()
+HandleRequest()
ConcreteHandler2
+HandleRequest()
ConcreteSubject ConcreteObserver
-subjectState -observerState
Client Invoker Allows an object to alter its behavior when its internal state changes
executes Context
+Request()
Receiver ConcreteCommand Command
+Action() +Execute() +Execute()
ConcreteStateA
+Handle()
State
Interpreter
+Handle()
ConcreteStateB
Given a language, defines a representation for its grammar along with an interpreter
that uses the representation to interpret sentences in the language +Handle()
Client Context
Strategy
TerminalExpression Defines a family of algorithms, encapsulate each one, and make them interchangeable
+Interpret(context)
AbstractExpression
+Interpret(context) Context
NonterminalExpression
+ContextInterface()
+Interpret(context)
StrategyA
Iterator +AlgorithmInterface()
Strategy
Given a language, defines a representation for its grammar along with an interpreter +AlgorithmInterface()
StrategyB
that uses the representation to interpret sentences in the language
+AlgorithmInterface()
Aggregate ConcreteAggregate
+CreateIterator() +CreateIterator() TemplateMethod
Visitor ConcreteVisitor
ConcreteColleague1
Colleague +VisitElementA(element) +VisitElementA(element)
+VisitElementB(element) +VisitElementB(element)
ConcreteColleague2
Client ConcreteElementA
Memento +Accept(visitor)
Element
Without violating encapsulation, capture and externalize an object's internal state so +Accept(visitor)
that the object can be restored to this state later ConcreteElementB
+Accept(visitor)
Originator Memento
-state -state
Caretaker
+SetMemento(memento) +GetState()
+CreateMemento() +SetState()