Selection Sort

Reading Time: 1 minute

Description

Selection Sort searches through the list of array to find the smallest item in the unsorted list.
Sorting starts from the left to the right, all the sorted elements reside on the left side of the array.
Selection sort is not a fast algorithm, because it uses nested loops to sort. It comes handy when we sort smaller data sets. It’s worse-case run time complexity is O(n2)

Code

The code can be also found in my Github Repository @ https://github.com/tugrulaslan/BlogCodeSnippets/tree/master/SortingAlgorithms

Big O Notation

Reading Time: 4 minutes

Definition

The Big O Notation is simplified analysis of an algorithm’s efficiency. It is also known as Landau’s Symbol. Big O Notation is used in Computer Science and Mathematics to describe the Asymptotic behavior of functions. Let’s study some of the characteristics;

  1. Big O Notation enlightens about the complexity of a target algorithm for a given input considered as “N”,
  2. Big O Notation is the abstraction of the efficiency in terms of the machine independence. The Algorithm must perform the same way on every operation system and hardware.
  3. Big O Notation does not concern about how much of time that an algorithm takes but how it performs under certain situations.
  4. Big O Notation gives us the “Time” and the “Space” constraints.

In addition to the second characteristic; when we run a program, we will have performance that is how much of time or hardware resource is used, and complexity how the algorithm acts and grows. Note that the Complexity affects the performance, but the other way around is not possible.

Furthermore, there are three types of measurements that I’ll explain and demonstrate those measurements in a different chapter.

Rules

Drop the constants

If you have a function that has a running time of 5N, that is realized as O(n). Because n gets bigger and the 5 is not the consideration anymore,

Observe all inputs

Different inputs and variables have different weights on identifying the notation. If you iterate in two different arrays you get O(a*b). Study the following pseudo code;

method(int[] array1, int[] array2){

For(int a : array1){//O(a)

For(int b : arrayb){//O(b)

System.out.println("match");//O(1)

}

}

}

Drop the low order terms

Certain terms dominate the other terms, in this case we drop the lower term(s). Here is the sequence of the terms. From the right to the left domination gets lower:

O(1) < O(log n) < O(n) < O(n log n) < O(n2) < O(2n) < O(n!)

Complexities

Big O Notation can be used to describe the Time Complexity and the Space Complexity of algorithms. Each of these subjects are different terms.

Time Complexity

The Time Complexity corresponds to the amount of time that an Algorithm takes to run. The Time Complexity has the following cases; Best, Average and Worst.

Space Complexity

The Space Complexity describes how much of a space the algorithm allocates in the memory according to the amount of given data.

Cases

In Big O Notation we have three cases:

  1. Best Case,
  2. Average Case,
  3. Worst Case

When algorithms are analyzed, generally “Worst Case is referred. It doesn’t mean that the rest of the cases are less important, but depending on the input, the Worst Case has a weight.

Notations

image courtesy www.bigocheatsheet.com

O(1) Constant

Constant time is a basic statement that has only Constants, in a different way the values that are solid and will not change. Regardless of amount of the data, the code executes the process in the time amount, this can be a variable definition, access in an array or a print out. The simplest examples would go for this:

Int x = (9/2)*12-1;

To find out the Big O Notation of such constants;

1.int a = (9/2)*12-1;//O(1)

2.int b = 100/2; //O(1)

3.int result a+b; //O(1)

System.out.println(result); //O(1)

Total time spent: O(1) + O(1) + O(1) + O(1) = O(1)

4*O(1)

(Constants are dropped)

O(n) Linear

linear time is known as the completion time grows for the given amount of data. A good example to it is the linear search in a loop that iterates through N amount of elements.

1.for(int i=0; i<N; i++){//O(n)

2.System.out.println(i)//O(1)

}

Total time spent: O(n)*O(1)=O(n)

1.int x = 55*3+(10-9); //O(1)

for(int i=0; i<N; i++){//O(n){
3.System.out.println(i)//O(1)

}

Total time spent: O(1) + O(n)*O(1)=O(n)

(Drop low order terms)

O(n2) Quadratic

the time completion of quadratic algorithms is proportional to the square of the given amount of data. Commonly we spot these sorts of algorithms in nested loops. In addition, the more nested loops exist, the square will become cubic O(n3) or more. The good example is the Bubble Sort. Furthermore, such algorithms dramatically hamper the performance if the amount of data increases.

O(2NExponential

Exponential algorithms are those whose performance doubles for every given input. We can basically spot such algorithms in recursive methods of calculations. For the sake of simplicity, I’ll give an example of Fibonacci numbers. As you will see, the method will call itself twice for the given input.

public int fibonacciNumbers(int number) {

  if (number <= 1) {

    return number;

  } else {

    return fibonacciNumbers(number - 1) + fibonacciNumbers(number - 2);

  }

}

O(n!) Factorial

Factorial algorithm that calculates all permutation of a given array is considered as O(n!). The most suitable example of this is the travelling sales man problem with the brute-force search.

O(log n) Logarithmic

The best way to explain logarithmic algorithms is to search in chunks of data by quadratic them and the rest will be assumed as O(n). Since we split it we will gain some time while looking up. The good world example would be the Binary Search Tree for these types of algorithms and they are very efficient, because increasing the amount of data has a minor effect at some point, because the amount of data is halved each time as it is seen with the Binary Search Tree.

O(n log n) Quasi Linear

Quasi linear algorithms are the ones hard to spot. The given values will be compared once. Essentially each comparison will reduce the possible final sorted data structure in half like in O(log n). Furthermore, the number of comparisons that will be performed is equal to log in the factorial of “n”. The comparisons are also equal to n log n this is how O(n log n) algorithms are formed. The mathematical representation as follows;

Sum of comparisons are equal to log n!

Divided comparisons are equal to log n + log(n-1) + … +log(1)//End of comparisons

The outcome is equal to n log n

Examples of Quasi linear complexities are Merge and Heap Sorts.

Further Reading

  1. Big O Cheat Sheet: A great web site that points out the Time and Space complexities of Data Structures and Algorithms.
  2. Stackoverflow Post: While making my research, I found an explanation of John very easy to explain Notations by using the same example.

Binary Tree

Reading Time: 6 minutes

Definition

Binary tree is a non-linear data structure that is composed of two nodes at most. This is how the name “Binary” is formed. However, it is not necessary for the Child Nodes that they have to have two nodes, in fact they can have even zero, we will observe such types in the following chapters.

Furthermore, there is also a Binary Tree implementation called “Binary Search Tree(a.k.a ordered binary tree)” that preserves data in a sorted fashion. From this point on, we will be talking and focusing on Binary Search Tree. Let’s apprehend the characteristics of Binary Search Tree:

  • Given key is compared to the root key, the lower placed on the left and the greater placed on the right,
  • There are two ways of traversals; breadth first and depth first (will be detailed in a sub chapter) compared to one-dimensional arrays and linked lists,
  • Average cases of Positional Access, Search, Insertion and Deletion operations are far faster in tree that is denoted as O(log n) in the Big O time complexity.

Additionally, during my research, I have found a very useful resource that exposes a visualized Binary Search Tree and its operations; https://www.cs.usfca.edu/~galles/visualization/BST.html

Let’s look into the source code how we can create a Binary Tree.

Node.java

public class Node {
    Node leftNode;
    Node rightNode;
    int key;

    Node(int key) {
        this.key = key;
    }
}

BinaryTree.java

public class BinaryTree {

    private Node rootNode;
    private final static int DATA_NOT_AVAILABLE = -1;

//The rest of the code can be obtained on GitHub
}

Glossary and Properties

Before diving into Binary Search Tree, we will need to have a ubiquitous language to apprehend all the terms used in this data structure.

Binary Tree Glossary

Root: The only top most element that has no other nodes above it,

Node: Every member in the tree is known as Node including the root as well,

Parent Node: The node that has two children,

Child Node: A node that is associated with a parent node

Leaf: A leaf is a node that DOES NOT have any children,

Path/Edge: The lines that connect all available nodes,

Sub tree: It is a triangle shape in a tree. Essentially a parent with its two child nodes,

Height: The height of a tree is the number of the edges from the Root node to its deepest leaf.

Some Binary Tree Height Samples as follow:

Binary Tree Glossary Height is three

Binary Tree Glossary height is four

Time and Space Complexities of Binary Tree

Binary Tree Big O Notation Image courtesy: www.bigocheatsheet.com

Types of Binary Trees

Balanced Binary Tree

Balanced and Unbalanced Trees

A Balanced Tree is composed of a balance between the left and the right nodes, but at most one side differs only by one, otherwise it will be considered as an Unbalanced Tree. The operations in a balanced tree are performed in O(log n) notation where n is the node number.
In Addition, Balanced Tree Type has other implementations such as AVL, Red-Black, Weight and Height Balanced Trees etc. It is a good practice to apprehend the definition of the balanced tree.

Unbalanced Binary Tree

Unbalanced Tree

Ordered data sets make up the unbalanced tree. In this type, most of the nodes are located on one side of the tree. In Unbalanced Trees, we cannot favor of fast operations denoted as O(log n), whereas it is actually O(n).

Full Binary Tree

Full Binary Tree

Full Binary Tree is a tree type that consists of a rule that indicates that leaves can have zero or nodes have two children.

L + I + 1

L: Number of leaf nodes,

I: Number of internal nodes

Complete Binary Tree

Complete Binary Tree

Complete Tree is a type of a Binary Tree in which;

  1. Every level must be completely filled,
  2. All leaf elements must lean towards left direction,
  3. Exceptionally the last leaf might have a right child node

Furthermore, Complete Binary Tree is also a Heap

Perfect Binary Tree

Perfect Binary Tree consists of Full and Complete Binary Trees with two conditions of :

  • all nodes have two children,
  • all leaves are on the same level.

In addition, the height of tree is 2h – 1

Tree Traversal

Tree Traversal is the acronym that is known as Tree Search is a type of an action that leads to visiting every single node in the tree and performing selection, insertion, updating and deletion. While going/traversing through there are number of ways to do so namely; Breadth First and Depth First traversals.

Tree Traversal

Breadth First Traversal

Breadth First Tree Traversal

Breadth First Traversal traverses the tree in a level fashion. It internally utilizes a Queue Data Structure, to visit nodes in layers as you can see the illustration. The algorithm of Breadth First Traversal goes;

public void breadthFirstTraversal() {
        if (rootNode == null)
            return;
        System.out.printf("***Breadth First Traversal***\n");
        Queue<Node> queue = new ArrayDeque<>();
        queue.add(rootNode);
        while (!queue.isEmpty()) {
            rootNode = queue.remove();
            System.out.println(rootNode.key);
            if (rootNode.leftNode != null)
                queue.add(rootNode.leftNode);
            if (rootNode.rightNode != null)
                queue.add(rootNode.rightNode);
        }
}

Console Output:

***Breadth First Traversal***
60
55
67
50
57
61
77
45
53

Depth First Traversal

Deep First travel is slightly different and more complicated compared to the Breadth first traversal. Basically, Depth first traversal, the actual focus is not the levels and layers but the Depth itself. Depth first algorithms will visit each node.

In Order Traversal

In Order Traversal

In Order Traversal has the following sequence:

  1. Left Node,
  2. Root Node,
  3. Right Node

Having said that when the traversal begins from the deepest left node. As the second item goes to the root, it is not the top root but the parent root. Then it follows the right node. As you see the above illustration, the algorithm starts in “45” the deepest left node and ends in “77” the highest right node in the tree. Observe the code for traversal:

private void inOrderTraversal(Node node) {

        if (node != null) {

            inOrderTraversal(node.leftNode);

            System.out.println(node.key);

            inOrderTraversal(node.rightNode);

        }

    }

Console Output:

***In Order Traversal***
45
50
53
55
57
60
61
67
77

Pre Order Traversal

Pre Order Traversal

Pre Order Traversal has the following sequence:

  1. Root Node,
  2. Left Node,
  3. Right Node

Having said that when the traversal begins from the root node. As the second item goes to the next left root. Then here the algorithm starts to visit the left and accordingly the right node. As you see the above illustration, the algorithm starts in “60” the root node and ends in “77” the highest right node in the tree. Observe the code for traversal:

private void preOrderTraversal(Node node) {

        if (node != null) {

            System.out.println(node.key);

            preOrderTraversal(node.leftNode);

            preOrderTraversal(node.rightNode);

        }

    }

Console Output:

***Pre Order Traversal***
60
55
50
45
53
57
67
61
77

Post Order Traversal

Post Order Traversal

Post Order Traversal has the following sequence:

  1. Left Node,
  2. Right Node,
  3. Root Node

Having said that when the traversal begins from the deepest left node. As the second item goes to the next right node. Last of all it visits the root node of the children. As you see the above illustration, the algorithm starts in “45” the deepest left node and ends in “60” the root node. Observe the code for traversal:

private void postOrderTraversal(Node node) {

        if (node != null) {

            postOrderTraversal(node.leftNode);

            postOrderTraversal(node.rightNode);

            System.out.println(node.key);

        }

    }

Console Output:

***Post Order Traversal***
45
53
50
57
55
61
77
67
60

Code

The full source code of the Binary Tree and the test cases can be obtained from my public GitHub repository. There will be more utility methods and test cases covering the chapter.

https://github.com/tugrulaslan/BlogCodeSnippets/tree/master/DataStructures

Creating a Java keystore

Reading Time: 1 minute

create a keystore file

$JAVA_HOME/bin/keytool -genkey -alias tugrulaslan.net -keyalg
RSA -keystore keystore.jks -keysize 2048

keystore1

Generate a certificate signing request (CSR) for an existing Java keystore

$JAVA_HOME/bin/keytool -certreq -alias tugrulaslan.net -keysto
re keystore.jks -file tugrulaslan.net.csr

Import a root or intermediate CA certificate to an existing Java keystore

$JAVA_HOME/bin/keytool -import -trustcacerts -alias root -file
 intermediate.crt -keystore keystore.jks

check certificates in keystore

$JAVA_HOME/bin/keytool -list -v -keystore keystore.jks

Check specific keystore entry using an alias

$JAVA_HOME/bin/keytool -list -v -keystore keystore.jks -alias mydomain

f

Bubble Sort

Reading Time: 1 minute

Description

Bubble sort will repeatedly compare and swap adjacent items. If the item on the left is greater, it swaps it with the right item. Basically the greater items are shifted towards the right direction.
Furthermore, the second iteration is stopped because the last items are sorted already we wont go though them again. Furthermore, Bubble Sort is not an efficient sorting algorithm because it uses nested loops. It is only useful for small data sets. It’s worse-case run time complexity is O(n2)

Code

The code can be also found in my Github Repository @ https://github.com/tugrulaslan/BlogCodeSnippets/tree/master/SortingAlgorithms

Java Object equals, hashCode, Hashing Collections and Hash Code Collision

Reading Time: 7 minutes

Introduction

In this blog post I’ll be focusing on something very fundamental and assumed as easy in the concept, but fairly the subject requires more focus and better apprehending. Besides that I am quite sure you’ll learn many interesting related to this topic.

Object equals and hashCode Methods

equals and hashCode methods are shipped with the java.lang.Object class as all the objects in Java extend this class even if you don’t implicitly extend it, the JVM will explicitly do favor for you. So what are these methods and the contracts we need to follow up.

The equals() Method

The method is a Boolean type that in the signature accepts another object that is used to compare the given object with the current object. The equals method can be called by collections explicitly or you ca use to compare two given objects. It is that simple. so after this point we need to follow the contacts while filling in our methodology. Before digging into that, I’d to highlight what happens if we don’t override the method.

The original method relies in the Object class checks only the are equal to each other this mainly falls into similarity of the same memory location.

public boolean equals(Object obj) {
        return (this == obj);
    }

The importance comes in handy when we really need to check “equality”. For instance for a given Person object, the equality means when the names and last names are important. So in this matter we need to override and provide our own implementation of the equals method. Before that we need to meet some contacts;

1. Check whether the given object is null,

2.Check whether the given object is the type of the actual object,

3.Check whether the objects are the same,

4.Then last of all check the attributes whether they are the same or not

Here is a proper way of overriding the method to meet the contract criteria;

@Override
        public boolean equals(Object o) {
            if(o == null) return false;
            if (!(o instanceof Person)) return false;
            if (this == o) return true;
            Person person = (Person) o;

            return getName().equals(person.getName());
        }

The hashCode() Method

The default implementation of the hashCode methods returns the memory location of the object, thus if we are going to work on the hashing collections, we need to provide a proper way of working hash code method. In the below “Hash Code Collision” chapter you will study more of this topic for proper implementations and other options. Furthermore in the “Hashing Collection” chapter you’ll also see why the hashCode method is vital to override.

Here is a proper way of overriding the method to meet the contract criteria;

@Override
       public int hashCode() {
           return getName().hashCode();
       }

Now I’d like to give out some examples to see in each situation how the code behaves;

1. Proper equals and hash code methods applied:

public class ProperImplementations {
    private static class Person {
        public Person(String name) {
            this.name = name;
        }

        private String name;

        public String getName() {
            return name;
        }

        @Override
        public boolean equals(Object o) {
            if(o == null) return false;
            if (!(o instanceof Person)) return false;
            if (this == o) return true;
            Person person = (Person) o;

            return getName().equals(person.getName());
        }

        @Override
        public int hashCode() {
            return getName().hashCode();
        }
    }

    public static void main(String[] args) {
        Person person = new Person("Tugrul");
        Person person2 = new Person("Oguz");
        Person person3 = new Person("Oguz");
        System.out.println("Person is equal to Person 2: " + person.equals(person2));
        System.out.println("Person 2 is equal to Person 3: " + person2.equals(person3));
        System.out.println("Person hashcode: " + person.hashCode());
        System.out.println("Person 2 hashcode: " + person2.hashCode());
        System.out.println("Person 3 hashcode: " + person3.hashCode());
    }
}

Console Output:

Person is equal to Person 2: false
Person 2 is equal to Person 3: true
Person hashcode: -1778884893
Person 2 hashcode: 2456221
Person 3 hashcode: 2456221

2. Methods are not overridden;

public class NoImplementation {
    private static class Person {
        public Person(String name) {
            this.name = name;
        }

        private String name;
    }

    public static void main(String[] args) {
        Person person = new Person("Tugrul");
        Person person2 = new Person("Oguz");
        Person person3 = new Person("Oguz");
        System.out.println("Person is equal to Person 2: " + person.equals(person2));
        System.out.println("Person 2 is equal to Person 3: " + person2.equals(person3));
        System.out.println("Person is hashcode: " + person.hashCode());
        System.out.println("Person 2 is hashcode: " + person2.hashCode());
        System.out.println("Person 3 is hashcode: " + person3.hashCode());
    }
}

Console Output:

Person is equal to Person 2: false
Person 2 is equal to Person 3: false
Person is hashcode: 1735600054
Person 2 is hashcode: 21685669
Person 3 is hashcode: 2133927002

Hashing Collections

So now let’s dive into one of the Hashing collection to see how we integrate the equals and hashCode methods with a real-life example. In this chapter I’ll be focusing on HashMap and its internals from Java Version 7, because some of hashing collections including HashMap have been enhanced by Oracle since the version 8. You can read this detailed technical article to see the improvements.

So the HashMap works on an Entry object of arrays not as key and value if you decompile it you will see this entry;

transient Entry[] table;

After this point we will need to dig into the Entry object and how the rest of the operations are handled;

static class Entry<K,V> implements Map.Entry<K,V> {
         final K key;
         V value;
         Entry<K,V> next;
         final int hash;
         // the rest is omitted
}

We know now the era of this data structure. Sometimes in the terminology, to make the understanding of the entry easier, the term “bucket” is used. The term corresponds to the Entry itself in this concept. Now it is time to see the mostly used methods to perform insertion and retrieval of objects in HashMap.

The internals of the put operation

public V put(K key, V value) {
       if (key == null)
           return putForNullKey(value);
       int hash = hash(key.hashCode());
       int i = indexFor(hash, table.length);
       for (Entry<K,V> e = table[i]; e != null; e = e.next) {
           Object k;
           if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
               V oldValue = e.value;
               e.value = value;
               e.recordAccess(this);
               return oldValue;
           }
       }

       modCount++;
       addEntry(hash, key, value, i);
       return null;
   }

Steps:

1.First checked if the key is null
1.1.For the null key: it’s placed in the 0 index,
1.2.If not then the hashCode() method of the Key which is the given object is called to retrieve the hash code,

2.the indexFor() method is then performed to identify the location of the object. It is calculated by the hashCode and the hash table length which is default 16,

3.If the index is empty then the object is inserted at this point. What if the index has another entry? this is the situation called “hash collision”. Then the equals() method is called to check whether the given objects are the same;
3.1. equals() returns true: the old value is replaced by the new value,
3.2. equals() returns false: the new object is linked to the existing object where you see the attribute “next” in the Entry object and the size of the HashMap is increased

The internals of the get operation

public V get(Object key) {
        if (key == null)
            return getForNullKey();
        int hash = hash(key.hashCode());
        for (Entry<K,V> e = table[indexFor(hash, table.length)];
             e != null;
             e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
                return e.value;
        }
        return null;
    }

Steps:

1.First the hash code of the key is calculated and the index is identified,
2.Then we are navigated to the index,
3.If no entry found in the index, the null value is returned,
4.if the entry exists;
4.1.The hashcode is copared,
4.2.1.Hash code matches: the equal methods is called for equality check, if returns true then the value is returned,
4.2.2.Hash code does not match: it will navigate to the next attribute and apply the same pattern in 4.2.1 step recursively, until the hashcode and equal methods return positive values.

Hash Code Collision

A collision happens when distinct keys produce the same hashCode() value that is not unique. In this case, typically the entries will be attached next to each other. Similar to hash code collision, you can also read about this SHA-1 collision security vulnerability found out by professionals. Furthermore, even String class survives with the same situation and will return the same hashCode for the given String values. Observe the below example for the prove;

import java.util.HashMap;

public class HashCodeCollisionExample {
    private static class Person {
        public Person(String name) {
            this.name = name;
        }

        private String name;

        public String getName() {
            return name;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof Person)) return false;

            Person person = (Person) o;

            return getName().equals(person.getName());
        }

        @Override
        public int hashCode() {
            return name.hashCode();
        }
    }

    public static void main(String[] args) {
        Person person = new Person("Aa");
        Person person2 = new Person("BB");
        Person person3 = new Person("BB");
        System.out.println("Person is equal to Person 2: " + person.equals(person2));
        System.out.println("Person 2 is equal to Person 3: " + person2.equals(person3));
        System.out.println("Person hashcode: " + person.hashCode());
        System.out.println("Person 2 hashcode: " + person2.hashCode());
        System.out.println("Person 3 hashcode: " + person3.hashCode());
        HashMap<Person, Person> hashMap = new HashMap<>();
        hashMap.put(person, person);
        hashMap.put(person2, person2);
        hashMap.put(person3, person3);
        hashMap.keySet().stream().forEach(p -> System.out.println(p.getName()));
    }
}

Console Output:

Person is equal to Person 2: false
Person 2 is equal to Person 3: true
Person hashcode: 2112
Person 2 hashcode: 2112
Person 3 hashcode: 2112
Aa
BB

Here come some trivial questions in the sense of Hash Collision;

What do we want with uniqueness? Can we not produce random keys?

By using random keys we will never find the inserted values in the HashMap. We shall mind the fact that, the given hash must be re-calculable  at a later to be found at the given index unlike to Encryption mechanisms e.g. hashing passwords that is one way and we just check the hash for the correction in the simple username and password security mechanisms.

What if we get rid of uniqueness and return the same hash, wouldn’t it work that way?

This approach also meets the contact well, however, first we’ll have benefited from the nature of the Hashing collection, which is we can use a simple List collection and give it a go. Other than that, traversing a LinkedList node each time and having all the expensive operations are also another considerations. HashMap is fast when we have the unique numbers and less linked nodes attached to each other.

If you are stuck with the hash code generation here I listed some options you can benefit of;

  • Objects.hash shipped with Java 7 and can be used even higher versions,
  • Apache Commons Hashcode builder, it also does good job but
  • Google Guava Oracle’s new implementation has also inspired from this library as well,
  • Josh Bloch’s Effective Java in Item 9, he emphasizes on using prime numbers, generally Eclipse and Intellij creates hash code by following Josh’s contract.

Builder Pattern in Java

Reading Time: 6 minutes

The Builder pattern eliminates building the complexity of the target object as well as eases the construction by providing such methods that will assemble the object same as building a set of blocks.
By implementing the Builder pattern, there won’t be any need of larger constructors, parameter objects or custom types. Furthermore, the Builder pattern is listed as a Creational Pattern. In JDK this pattern can be seen in java.lang.StringBuilder‘s append method.

In real life examples, the pattern consists of;

  • Client: is the endpoint that makes a request to the product,
  • Product: The actual complex object itself which is assembled by the concrete builders,
  • Director: Has only one responsibility to make a call to the Builder itself,
  • Builder: Hold the common methods for Concrete Builders of how the product will be shaped,
  • Concrete Builder: They build creates a specific Product, provides ways to decorate the Product as well as constructs the product and returns it.

Advantages:
-Removing multiple and complex constructor creations,
-Providing a method that checks whether the required fields are filled,
-Providing a mechanism to check whether given parameters meet the requirements
-Immutability, this is mostly the developers are looking forward to striving and benefiting it

Disadvantages:
-For each specific Product, there must be a concrete builder created,

For the sake of better apprehending the pattern which is in a way complex, I’ll be giving two examples an Intermediate that gives an overall look to quickly understanding the pattern
and an advanced example which demonstrates all the Roles that are defined above.

Intermediate Example

In this example you will study a simple Person object that will be constructed by a static Person builder class.
The direct construction of the Person object is disallowed by marking the constructor as private. In addition, I have included a simple business logic within the build method that will give you an idea how business logic can be implemented properly.
Last of all, I have created test cases to see the possible behaviors and outcome of the object.

Person Class

package com.tugrulaslan.builderpattern;

import java.util.Date;

public class Person {
    /**
     * Required Fields
     */
    private final String firstName;
    private final String lastName;
    private final Date dateOfBirth;
    /**
     * Optional Fields
     */
    private final String phoneNumber;
    private final String city;

    /**
     * The private Constructor accepts only the builder which holds the data to initiate the fields in the Person class,
     * If optional field are left off null, they are assigned to empty values to prevent NullPointerException
     *
     * @param personBuilder
     */

    private Person(final PersonBuilder personBuilder) {
        this.firstName = personBuilder.firstName;
        this.lastName = personBuilder.lastName;
        this.dateOfBirth = personBuilder.dateOfBirth;
        this.phoneNumber = personBuilder.phoneNumber == null ? "" : personBuilder.phoneNumber;
        this.city = personBuilder.city == null ? "" : personBuilder.city;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public Date getDateOfBirth() {
        return dateOfBirth;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public String getCity() {
        return city;
    }

    public static class PersonBuilder {
        /**
         * Required Fields, will be marked as final in the builder class
         */
        private final String firstName;
        private final String lastName;
        private final Date dateOfBirth;
        /**
         * Optional Fields, will not be marked as final in the builder class
         */
        private String phoneNumber;
        private String city;

        /**
         * Constructor of static PersonBuilder that initiates the required fields
         *
         * @param firstName   A String type field, corresponds to the firstName field in the Person object, required,
         * @param lastName    A String type field, corresponds to the lastName field in the Person object, required ,
         * @param dateOfBirth A java.util.Date type field, corresponds to the dateOfBirth field in the Person object, required.
         */
        public PersonBuilder(final String firstName, final String lastName, final Date dateOfBirth) {
            this.firstName = firstName;
            this.lastName = lastName;
            this.dateOfBirth = dateOfBirth;
        }

        /**
         * @param phoneNumber A String type field, correspond to the phoneNumber field in the Person object, optional.
         * @return returns the same PersonBuilder object
         */
        public PersonBuilder phoneNumber(String phoneNumber) {
            this.phoneNumber = phoneNumber;
            return this;
        }

        /**
         * @param city A String type field, correspond to the city field in the Person object, optional.
         * @return returns the same PersonBuilder object
         */
        public PersonBuilder city(String city) {
            this.city = city;
            return this;
        }

        /**
         * Person builder object that has all the required business rules
         *
         * @return A Person object unless the business rules are met, otherwise exceptions will be thrown
         */
        public Person buildPerson() {
            Person person = new Person(this);
            if (person.firstName == null || person.firstName.length() == 0) {
                throw new IllegalArgumentException("First Name cannot be null or empty");
            } else if (person.lastName == null || person.lastName.length() == 0) {
                throw new IllegalArgumentException("Last Name cannot be null or empty");
            } else if (person.dateOfBirth == null) {
                throw new IllegalArgumentException("Birth date cannot be null");
            } else {
                return person;
            }
        }
    }
}

Person Class Test Case

package com.tugrulaslan.test;

import com.tugrulaslan.builderpattern.Person;
import org.junit.Test;

import java.util.Date;

import static org.junit.Assert.assertEquals;

public class PersonTest {

    private final static String FIRST_NAME = "Tugrul";
    private final static String LAST_NAME = "Aslan";
    private final static Date DATE_OF_BIRTH = new java.util.Date();
    private final static String PHONE_NUMBER = "+48754345325";
    private final static String CITY = "Wrocław";

    @Test(expected = java.lang.IllegalArgumentException.class)
    public void testRequiredFieldInvalidValue() {
        Person person = new Person.PersonBuilder(null, LAST_NAME, null).buildPerson();
    }

    @Test
    public void testProperValuesOptionalValuesEmpty() {
        Person person = new Person.PersonBuilder(FIRST_NAME, LAST_NAME, DATE_OF_BIRTH).buildPerson();
        assertEquals(person.getFirstName(), FIRST_NAME);
        assertEquals(person.getLastName(), LAST_NAME);
        assertEquals(person.getDateOfBirth(), DATE_OF_BIRTH);
        assertEquals(person.getPhoneNumber(), "");
        assertEquals(person.getCity(), "");
    }

    @Test
    public void testProperValuesOptionalValuesFilledIn() {
        Person person = new Person.PersonBuilder(FIRST_NAME, LAST_NAME, DATE_OF_BIRTH)
                .phoneNumber(PHONE_NUMBER)
                .city(CITY)
                .buildPerson();
        assertEquals(person.getFirstName(), FIRST_NAME);
        assertEquals(person.getLastName(), LAST_NAME);
        assertEquals(person.getDateOfBirth(), DATE_OF_BIRTH);
        assertEquals(person.getPhoneNumber(), PHONE_NUMBER);
        assertEquals(person.getCity(), CITY);
    }
}

Advanced Example

Advanced example compared to the Intermediate one, is fairly exposes all roles in depth. To better apprehend the topic I have given a kebab example where I’ll walk you through making kebab in a code level from the scratch.
Test cases will prove the outcome and each builder will properly assemble an example of the specific kind of kebab. To redefine each role that is used in this example;

  • Client: KebabTest,
  • Product: Kebab,
  • Director: Chef,
  • Builder: KebabBuilder,
  • Concrete Builder: AdanaKebab, UrfaKebab and ChickenKebab.

KebabTest

package com.tugrulaslan.test;

import com.tugrulaslan.builderpattern.*;
import org.junit.Test;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

public class KebabTest {

    @Test
    public void adanaKebabTestCase() {
        Chef chef = new Chef();
        KebabBuilder adanaKebabBuilder = new AdanaKebab();
        chef.setKebabBuilder(adanaKebabBuilder);
        chef.makeKebab();
        Kebab adanaKebab = chef.getKebab();
        assertNotNull(adanaKebab);
        assertEquals(adanaKebab.getKebabName(), "Adana Kebab");
        assertEquals(adanaKebab.getMeatType(), MeatType.REDMEAT);
        assertTrue(adanaKebab.isSpicy());
        assertEquals(adanaKebab.getPrice(), 10);
    }

    @Test
    public void urfaKebabTestCase() {
        Chef chef = new Chef();
        KebabBuilder urfaKebabBuilder = new UrfaKebab();
        chef.setKebabBuilder(urfaKebabBuilder);
        chef.makeKebab();
        Kebab urfaKebab = chef.getKebab();
        assertNotNull(urfaKebab);
        assertEquals(urfaKebab.getKebabName(), "Urfa Kebab");
        assertEquals(urfaKebab.getMeatType(), MeatType.REDMEAT);
        assertFalse(urfaKebab.isSpicy());
        assertEquals(urfaKebab.getPrice(), 9);
    }

    @Test
    public void chickenKebabTestCase() {
        Chef chef = new Chef();
        KebabBuilder chickenKebabBuilder = new ChickenKebab();
        chef.setKebabBuilder(chickenKebabBuilder);
        chef.makeKebab();
        Kebab chickenKebab = chef.getKebab();
        assertNotNull(chickenKebab);
        assertEquals(chickenKebab.getKebabName(), "Chicken Kebab");
        assertEquals(chickenKebab.getMeatType(), MeatType.CHICKEN);
        assertTrue(chickenKebab.isSpicy());
        assertEquals(chickenKebab.getPrice(), 7);
    }
}

Kebab

package com.tugrulaslan.builderpattern;


/**
 * Kebab class is in the Product Role
 */
public class Kebab {
    private String kebabName;
    private MeatType meatType;
    private boolean spicy;
    private int price;

    public String getKebabName() {
        return kebabName;
    }

    public void setKebabName(String kebabName) {
        this.kebabName = kebabName;
    }

    public MeatType getMeatType() {
        return meatType;
    }

    public void setMeatType(MeatType meatType) {
        this.meatType = meatType;
    }

    public boolean isSpicy() {
        return spicy;
    }

    public void setSpicy(boolean spicy) {
        this.spicy = spicy;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        this.price = price;
    }
}

Chef

package com.tugrulaslan.builderpattern;

/**
 * Chef class is in the Director Role
 */
public class Chef {
    private KebabBuilder kebabBuilder;

    public void setKebabBuilder(KebabBuilder kebabBuilder) {
        this.kebabBuilder = kebabBuilder;
    }

    /**
     * @return kebab object that is assembled by the concrete kebab builder class
     */
    public Kebab getKebab() {
        return kebabBuilder.kebab;
    }

    /**
     * The void method that calls all the available methods in the concrete class
     */
    public void makeKebab() {
        kebabBuilder.createNewKebab();
        kebabBuilder.assignKebabName();
        kebabBuilder.assignMeatType();
        kebabBuilder.makeSpicy();
        kebabBuilder.setKebabPrice();
    }
}

KebabBuilder

package com.tugrulaslan.builderpattern;

/**
 * KebabBuilder class is in the Builder Role
 */
public abstract class KebabBuilder {
    protected Kebab kebab;

    /**
     * @return current Kebab Object
     */
    public Kebab getKebab() {
        return kebab;
    }

    /**
     * Returns a new instance of Kebab object
     */
    public void createNewKebab() {
        kebab = new Kebab();
    }

    /**
     * An abstract template to assign a name to the Kebab
     */
    public abstract void assignKebabName();

    /**
     * An abstract template to assign the Kebab's Meat Type
     */
    public abstract void assignMeatType();

    /**
     * An abstract template to the Kebab spicy or not
     */
    public abstract void makeSpicy();

    /**
     * An abstract template to set Kebab's price
     */
    public abstract void setKebabPrice();
}

AdanaKebab

package com.tugrulaslan.builderpattern;

/**
 * Adana Kebab concrete class is in the Concrete Builder Role that represents its specifications.
 */
public class AdanaKebab extends KebabBuilder {

    @Override
    public void assignKebabName() {
        kebab.setKebabName("Adana Kebab");
    }

    @Override
    public void assignMeatType() {
        kebab.setMeatType(MeatType.REDMEAT);
    }

    @Override
    public void makeSpicy() {
        kebab.setSpicy(true);
    }

    @Override
    public void setKebabPrice() {
        kebab.setPrice(10);
    }
}

UrfaKebab

package com.tugrulaslan.builderpattern;

/**
 * Urfa Kebab concrete class is in the Concrete Builder Role that represents its specifications.
 */
public class UrfaKebab extends KebabBuilder {

    @Override
    public void assignKebabName() {
        kebab.setKebabName("Urfa Kebab");
    }

    @Override
    public void assignMeatType() {
        kebab.setMeatType(MeatType.REDMEAT);
    }

    @Override
    public void makeSpicy() {
        kebab.setSpicy(false);
    }

    @Override
    public void setKebabPrice() {
        kebab.setPrice(9);
    }
}

ChickenKebab

package com.tugrulaslan.builderpattern;

/**
 * Chicken Kebab concrete class is in the Concrete Builder Role that represents its specifications.
 */
public class ChickenKebab extends KebabBuilder{

    @Override
    public void assignKebabName() {
        kebab.setKebabName("Chicken Kebab");
    }

    @Override
    public void assignMeatType() {
        kebab.setMeatType(MeatType.CHICKEN);
    }

    @Override
    public void makeSpicy() {
        kebab.setSpicy(true);
    }

    @Override
    public void setKebabPrice() {
        kebab.setPrice(7);
    }
}

 

Immutable Objects in Java

Reading Time: 3 minutes

Immutability of an object indicates that once an object is constructed with given values, its state and values cannot be altered. In case of any value change must result in new object creation.

Out of box Java offers some Immutable objects for instance java.lang.String, java.lang.Integer, java.lang.Float, java.math.BigDecimal.

Immutable objects make generally a good use in concurrent programming. The reliability is a key aspect in concurrent programming, so that corrupted data sets and objects may cause unwanted behaviors in applications.

Pros

  • Reliable and Atomic Data: The given data during the initialization of the immutable object is always the same, thus the data set is ensured and atomic. Furthermore, An Immutable object can be a good candidate to be the Key in Map collection,
  • Thread Safety/Concurrency: The content of an immutable object is valid and no method may cause an alteration of the state thus it is thread safe,
  • Garbage Collection: The garbage collectors can easily identify and make decisions on immutable objects.

Cons

  • Mass of objects: Allocating lots of new objects may cause to increase the memory allocation for modifications. This can be somehow manageable while employing a good model of java memory management.

Rules to define an Immutable Object:
Immutability of an object indicates that once an object is constructed with given values, its state and values cannot be altered. In case of any value change must result in new object creation.
Out of box Java offers some Immutable objects for instance java.lang.String, java.lang.Integer, java.lang.Float, java.math.BigDecimal.
Immutable objects make generally a good use in concurrent programming. The reliability is a key aspect in concurrent programming, so that corrupted data sets and objects may cause unwanted behaviors in applications.

Pros:
-Reliable and Atomic Data: The given data during the initialization of the immutable object is always the same, thus the data set is ensured and atomic. Furthermore, An Immutable object can be a good candidate to be the Key in Map collection,
-Thread Safety/Concurrency: The content of an immutable object is valid and no method may cause an alteration of the state thus it is thread safe,
-Garbage Collection: The garbage collectors can easily identify and make decisions on immutable objects,

Cons:
-Allocating lots of new objects may cause to increase the memory allocation for modifications. This can be somehow manageable while employing a good model of java memory management.

Rules to define an Immutable Object

1. Mark the designated immutable class as final; this will disallow the class to be subclasses or its methods to be overridden,
2. Mark all the fields with the final keyword and package access as private, this way fields will not be discoverable for other classes, as well as the values of fields will be forced to be initially set,
3. Mark the no arg constructor as private thus; creation of an empty valued object will be prevented,
4. Provide only one constructor and mark it as public to force callers to initialize all the fields,
5. Elimination of any methods that may change the state known as Setter Methods,
6. Last of all in case of having a mutable class as field member;
a. Mark it as final, so that its value can be assigned once only,
b. Disallow to have methods that will change the object state,
c. Perform to clone of the object not the object reference via getter methods, thus the alteration will be prevented.

Sample Immutable Object

import java.util.Collections;
import java.util.Date;
import java.util.List;

//Rule #1
public final class Student {
    /**
     * Immutable Object Field Declarations
     */
  //Rule #2
    private final String name;
    private final String lastName;
  //Rule #6a
    private final Date birthDate;
    private final List<String> classes;

    /**
     * Immutable Object Constructor Declarations
     */
  //Rule #3
    private Student() {
        this(null, null, null, null);
    }

  //Rule #4
    public Student(String name, String lastName, Date birthDate, List<String> classes) {
        this.name = name;
        this.lastName = lastName;
        this.birthDate = birthDate;
        this.classes = classes;
    }
  
  //Rule #5 and #6b- No setter methods exist

    /**
     * Immutable Object Getter Method Declarations
     */
    public String getName() {
        return name;
    }

    public String getLastName() {
        return lastName;
    }

  // Rule #6c
    public Date getBirthDate() {
        return (Date) birthDate.clone();
    }

    public List getClasses() {
        return Collections.unmodifiableList(classes);
    }
}

 

JSF Input text placeholder

Reading Time: 1 minute

In the Tag description add the pt entry and its corresponding web address

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:pt="http://xmlns.jcp.org/jsf/passthrough">

in the input text declaration

<h:inputText styleClass="form-control" 
pt:placeholder="Enter Search Value" required="true"
requiredMessage="Please enter search value"
value="#{orderController.keyword}" id="keywordSearch"/>

Installing External Jars to Local Maven Repository

Reading Time: 1 minute

Central Maven repository has a large variety of libraries https://mvnrepository.com however there are times that we may be in need of installing such 3rd party jars that are not offered in the central in mavenized projects. This command will allow you to install such jars to your local M2 folder. You need to make sure that if multiple developers are working on the project that experiences this situation, the participants must also carry out the same procedure.

The Command

[bash lang=”bash” smarttabs=”true” tabsize=”4″ wraplines=”true”]mvn install:install-file -Dfile={FILELOCATION}
-DgroupId=GROUPID/KNOWNASPACKAGENAME -DartifactId=ARTIFACTID
-Dversion=VERSION -Dpackaging=PACKAGINGTYLE[/bash]

Example Command

[bash smarttabs=”true” tabsize=”4″ wraplines=”true”]mvn install:install-file -Dfile=C:\myjar1-0.jar
-DgroupId=com.tugrulaslan -DartifactId=MyJar
-Dversion=1.0 -Dpackaging=jar[/bash]

Usage in pom.xml

<dependency>
<groupId>com.tugrulaslan</groupId>
<artifactId>MyJar</artifactId>
<version>1.0</version>
</dependency>

External Links
https://maven.apache.org/guides/mini/guide-3rd-party-jars-local.html