Friday, 15 December 2017

Iterative Binary Tree PreOrder Traversal in Java - Without Recursion

This is the second article on binary tree pre-order traversal in Java. In the first part, I have shown you how to traverse a binary tree with pre-order traversal using recursion, and in this article, you will learn how to implement pre-order traversal without using recursion. Just to revise, pre-order is a depth-first algorithm, where the depth of the tree is first explored before traversing sibling. In preOrder traversal, first, node or root is visited, then left subtree, and right subtree, hence it is also known as NLR (Node-Left-Right) algorithm. You might know that when you use recursion, methods calls are stored in an internal Stack which unwinds itself when algorithm reaches the base case. When recursion is not allowed, you can use the Stack data structure to create the same effect, in fact, this is also a common technique to convert a recursive algorithm into an iterative one.

Wednesday, 13 December 2017

How to implement PreOrder traversal of Binary Tree in Java

The easiest way to implement the preOrder traversal of a binary tree in Java is by using recursion. The recursive solution is hardly 3 to 4 lines of code and exactly mimic the steps, but before that, let's revise some basics about a binary tree and preorder traversal. Unlike array and linked list which have just one way to traversed i.e. linearly, binary tree has several ways to traverse all nodes e.g. preorder, postorder and inorder. But, tree traversal algorithms are mainly divided into two categories, the depth-first algorithms, and breadth-first algorithms. In depth-first, you go deeper into a tree before visiting the sibling node, for example, you go deep following left node before you come back and traverse the right node. On breadth-first traversal, you visit the tree on its breadth i.e. all nodes of one level is visited before you start with another level top to bottom. The PreOrder, InOrder, and PostOrder traversals are all examples of depth-first traversal algorithms.

Monday, 11 December 2017

Java 8 compute() and computeIfPresent() Example

The JDK 8 has added several useful methods in existing interfaces e.g. java.util.Map, java.util.Collection, and java.util.concurrent.ConcurrentMap. Thanks to default methods, the much-needed evolution of existing interfaces become possible. Out of many useful methods, one method which stands out to me is the compute() method, which allows you to update a value in ConcurrentHashMap atomically. As per Java documentation, The compute() function tries to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping). The entire function is performed atomically.

Friday, 8 December 2017

How to convert JSON String to Java Object - Gson/JSON Deserialization Example

You have learned how to convert a Java object to JSON String and in today's article, you will learn the opposite, i.e. converting a JSON String to Java object. The first example was known as JSON serialization example and this one is known as JSON deserialization because we are creating a Java object from a String. The idea is very similar to classical Serialization in Java where you convert a Java object to another binary format which can be transported over the network or can be saved in the disk for further usage. That's why the process of converting a Java object to JSON is known as serialization and converting a JSON document to Java object is known as De-Serialization. You can use any JSON library to perform serialization and de-serialization e.g. Jackson Databind, Gson, or Json-simple.  In this program, I'll show you how to use Gson to create a Java object from given JSON String.

Wednesday, 6 December 2017

Difference between Executor, ExecutorService and Executers class in Java

All three classes Executor, ExecutorService, and Executers are part of Java's Executor framework which provides thread pool facilities to Java applications. Since creation and management of Threads are expensive and operating system also imposes restrictions on how many Threads an application can spawn, it's a good idea is to use a pool of thread to execute tasks in parallel, instead of creating a new thread every time a request come in. This not only improves the response time of application but also prevent resource exhaustion errors like "java.lang.OutOfMemoryError: unable to create new native thread". A thread pool which is created when an application is a startup solves both of these problems. It has ready threads to serve clients when needed and it also has a bound on how many threads to create under load.