A Simple Topic Implementation using Java Observer/Observable

We have these 5 components:
1.) JmsBroker
2.) Topic
3.) Consumer
4.) Producer
5.) Main

JmsBroker contains all topics details. JmsBroker will provider methods like ‘addObserver’ so that consumers can attach themselves to topics and ‘sendMessageToTopic’ method so that producers can call this method to send message to a particular topic.
Topic is a container of all messages published to it and extends Observable.
Producer is the one who publishes messages to JmsBroker with destination which is a topicName.
Consumer class is actually an observer of Topic and implements Observer.
Main class will stitch all components together.

JmsBroker

package MessageQueue;

import java.util.*;

/**
 * Created by mdev on 4/28/15.
 */
public class JmsBroker {

    private final Map<String, Topic> topicMap = new HashMap<>();

    public void sendMessage(String topicName,String msg) {
        if(!topicMap.containsKey(topicName)) {
            Topic topic = new Topic(topicName);
            topicMap.put(topicName, topic);
        }
        topicMap.get(topicName).addMessage(msg);
    }

    public void addObserver(Consumer o){
        if(!topicMap.containsKey(o.getTopicName())) {
            topicMap.put(o.getTopicName(), new Topic(o.getTopicName()));
        }
        topicMap.get(o.getTopicName()).addObserver(o);
    }


}

Topic

package MessageQueue;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Observable;
import java.util.Observer;

/**
 * Created by mdev on 4/28/15.
 */

public class Topic extends Observable {

    private String name;
    private Deque<String> queue = new ArrayDeque<>();

    Topic(String name) {
        this.name = name;
    }

    public void addMessage(String str) {
        queue.add(str);
        this.setChanged();
        this.notifyObservers(str);
    }
}

Consumer

package MessageQueue;

import java.util.Observable;
import java.util.Observer;

/**
 * Created by mdev on 4/28/15.
 */
public class Consumer implements Observer {


    private String topicName;
    private String name;

    Consumer(String name, String topicName) {
        this.topicName = topicName;
        this.name = name;
    }


    @Override
    public void update(Observable o, Object arg) {
        System.out.println("Consumer :" + name + " got message : " + arg + " from topic : " + topicName);
    }

    public String getTopicName() {
        return topicName;
    }

}

Producer

package MessageQueue;

/**
 * Created by mdev on 4/28/15.
 */
public class Producer {


    String topicName;
    JmsBroker jmsBroker;

    public Producer(String topicName, JmsBroker jmsBroker) {
        this.jmsBroker = jmsBroker;
        this.topicName = topicName;
    }

    public void sendMessage() {
        new Thread() {
            public void run() {
                int count = 0;
                while (true) {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    jmsBroker.sendMessage(topicName, "Message  " + count++ + " From : " + topicName);
                }
            }
        }.start();
    }
}

Main

package MessageQueue;

/**
 * Created by mdev on 4/28/15.
 */
public class Main {

    public static void main(String[] args) throws InterruptedException {
        JmsBroker jmsBroker = new JmsBroker();

        String topicName = "Topic1";

        Producer p1  = new Producer(topicName, jmsBroker);

        Consumer c1 = new Consumer("Consumer1",topicName);

        Consumer c2 = new Consumer("Consumer2",topicName);

        jmsBroker.addObserver(c1);

        jmsBroker.addObserver(c2);

        p1.sendMessage();
    }
}
Advertisements

Some Basic SQL Practise

CREATE TABLE employee (
id serial,
name varchar,
dept_id int4,
salary int4,
CONSTRAINT employee_pkey PRIMARY KEY (id)
);

CREATE TABLE department (
id serial,
name varchar,
CONSTRAINT department_pkey PRIMARY KEY (id)
);

insert into employee (name,salary,dept_id) values (‘EmpA’,3000,1);
insert into employee (name,salary,dept_id) values (‘EmpB’,2100,1);
insert into employee (name,salary,dept_id) values (‘EmpC’,100,2);
insert into employee (name,salary,dept_id) values (‘EmpD’,4500,3);
insert into employee (name,salary,dept_id) values (‘EmpE’,10000,1);
insert into employee (name,salary,dept_id) values (‘EmpF’,3500,4);
insert into employee (name,salary,dept_id) values (‘EmpG’,5000,3);

insert into department (name) values (‘dept1’);
insert into department (name) values (‘dept2’);
insert into department (name) values (‘dept3’);
insert into department (name) values (‘dept4’);

Q1 Find the employee having ‘kth’ largest salary.


select name,salary from
(select name,salary from employee order by salary desc limit k) t
order by t.salary limit 1;

Q2 Find all departments with max salary.


select d.name,max(e.salary) from employee e  right join department d on e.dept_id = d.id group by d.name order by d.name;

Q3. Find all departments with max salary along with employee name.

select emp.name,emp.salary,temp.dept_name from employee emp inner join (
select d.name as dept_name,d.id as dept_id, max(e.salary) as salary from employee e right join department d
on e.dept_id = d.id
group by d.name,d.id order by d.name) temp on temp.dept_id = emp.dept_id and emp.salary=temp.salary;

String Path In Matrix

How to implement a function to check whether there is a path for a string in a matrix of characters?  It moves to left, right, up and down in a matrix, and a cell for a movement. The path can start from any entry in a matrix. If a cell is occupied by a character of a string on the path, it cannot be occupied by another character again.

For example, the matrix below with three rows and four columns has a path for the string “BCCED” (as highlighted in the matrix). It does not have a path for the string “ABCB”, because the first “B” in the string occupies the “B” cell in the matrix, and the second “B” in the string cannot enter into the same cell again.

A B C E
S F C S
A D E E

This can be solved easily using recursive approach.

package client;

/**
 * Created by mdev on 4/15/15.
 */
public class FindStringPathInMatrix {

    static int rows = 3;
    static int cols = 4;

    public static void main(String[] args) {
        char[][] mat = {{'A', 'B', 'C', 'E'}, {'S', 'F', 'C', 'S'}, {'A', 'D', 'E', 'E'}};
        
        boolean result = false;
        String input = &quot;BCCEDD&quot;;
        for (int i = 0; i &lt; cols; i++) {
            if(!result)
                result = exists(mat, input, 0, i);
        }
        for (int i = 0; i &lt; cols; i++) {
            if(!result)
                result = exists(mat,input, rows - 1, i);
        }
        for (int i = 0; i &lt; rows; i++) {
            if(!result)
                result = exists(mat, input, i, 0);
        }
        for (int i = 0; i &lt; rows; i++) {
            if(!result)
                result = exists(mat,input, i, cols-1);
        }
        System.out.println(result);

    }

    public static boolean exists(char[][] mat, String str, int i, int j) {
        if (i == rows || i &lt; 0 || j == cols || j &lt; 0)
            return false;

        if (str.length() == 0)
            return true;

        if (mat[i][j] != '0' &amp;&amp; mat[i][j] == str.charAt(0)) {
            char temp = mat[i][j];
            mat[i][j] = '0';

            if (exists(mat, str.substring(1), i + 1, j))
                return true;

            if (exists(mat, str.substring(1), i - 1, j))
                return true;

            if (exists(mat, str.substring(1), i, j - 1))
                return true;

            if (exists(mat, str.substring(1), i, j + 1))
                return true;

            mat[i][j] = temp;
        }
        return false;
    }
}

Missing Number in Sorted Array(N spaces) having values from 0-N

If we want to insert 0-N elements in an array with N spaces, one element will get missed.
e.g For N = 5
input[] 0,1,3,4,5 2 is missing here.

Since we know array is sorted we can do better than O(n), by using Binary Search. If all elements are correctly placed we should get input[index] == index for all elements.

So, if arr[index] == index Search in RIGHT

if arr[index] != index …. Search in LEFT but before going LEFT check if just left is on correct position or not. If just left position is correct, middle is the answer.

Here is the code for this :

public static int findUnMatchedIndex(int[] arr, int start, int end){
        int result;
        if(end - start == 1)
            return arr[end] == end?  (arr[start] == start ? -1:start) : end;
        int middle = (end-start)/2 + start;
        if(arr[middle] == middle)
            result = findUnMatchedIndex(arr,middle+1,end);
        else
            result = (arr[middle - 1] == middle -1) ? middle : findUnMatchedIndex(arr,start,middle-1);
        return result;
    }

Root to leaf path sum equal to a given number

There are multiple ways to solve this problem. Solution below has two ways:
1.) Keep recurse and pass the sum to child nodes until we reach the leave node. If at leave node sum is equal to target given. Print that node and return true which will signal that such target exists.
Now, start printing all such nodes which get signal as true.

2.) In this way we explicitly using Stack. This way we can print multiple such paths.


   static int target = 21;
   static Deque<Integer> stack = new ArrayDeque<>();

   public static void main(String... args){
      Node root = createTree(new int[]{10,8,2,3,5,2,-1});
      printPath(root,0);
      System.out.println();
      printPathUsingStack(root, 0);      
   }


   private static boolean printPath(Node root, int sum) {
        if(root == null)
            return false;
        if(root.left == null && root.right == null){
            if(sum + root.data == target){
                System.out.print(root.data + " ");
                return true;
            }
        }
        if(printPath(root.left,sum+root.data) || printPath(root.right,sum+root.data)) {
            System.out.print(root.data + " ");
            return true;
        }
        return false;
    }

    private static void  printPathUsingStack(Node root, int sum) {
        if(root == null)
            return ;
        if(root.left == null && root.right == null){
            if(sum + root.data == target){
                System.out.print(root.data);
                stack.stream().forEach(num -> System.out.print(" " + num));
                return ;
            }
        }
        stack.push(root.data);
        printPathUsingStack(root.left,sum + root.data);
        printPathUsingStack(root.right,sum + root.data);
        stack.pop();
    }


   

IntellijIdea shortcuts …

I switched from Eclipse to Intellij recently. This is the list of the shortcuts(for Mac) i use frequently.

Open Any File
Cmd + Shift + O

List of last opened files
Cmd + E

Find in all files
Cmd + Shift + F

Replace in all Files
Cmd + Shift + R

Refactor code
Cmd + Alt + L

Run Java application
Ctrl + Shift + R

Suggestions for import/add unimplemented methods
Alt + Enter

Code Completion
Ctrl + Space

Refactoring like renaming …
Ctrl + T

Getter/Setter/Constructor/toString/equals/override
Cmd + N

This will automatically create public static void main(String[] args)
psvm + tab

System.out.println
sout + tab

This will create print statement with last user variable
soutv + tab

This will create print statement with class and method name
soutm + tab

for loop
fori + tab
For inner loops, again type fori and tab. It will create one more loop with new variable.

Translating Numbers to Strings

Question: Given a number, please translate it to a string, following the rules: 1 is translated to ‘a’, 2 to ‘b’, …, 12 to ‘l’, …, 26 to ‘z’. For example, the number 12258 can be translated to “abbeh”, “aveh”, “abyh”, “lbeh” and “lyh”, so there are 5 different ways to translate 12258. How to write a function/method to count the different ways to translate a number?


package recursive;

public class NumberToString {

 public static void main(String... args){
 translateIntegerToString(11,"");
 }

 private static void translateIntegerToString(Integer input, String soFar){
 if(input == 0)
 System.out.println(new StringBuilder(soFar).reverse());
 if(input%10 > 0)
 translateIntegerToString(input/10,soFar+intToChar(input%10));
 if(input%100 > 9 && input%100 <=26)
 translateIntegerToString(input/100,soFar+intToChar(input%100));
 }

 private static char intToChar(int n){
 return (char) (n+64);
 }

}