Sunday, May 10, 2015

Sorting a collection by more than one field

Let's say we have an Employee Object with the fields as given below.

class Employee implements Comparable {

    private int empid;
    private String deptname;
    private String name;
    private float salary;

    public int getEmpid() {
        return empid;
    }

    public String getDeptname() {
        return deptname;
    }

    public String getName() {
        return name;
    }

    public float getSalary() {
        return salary;
    }

    public Employee(int empid, String deptname, String name, float salary) {
        this.empid = empid;
        this.deptname = deptname;
        this.name = name;
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "Employee{" + "empid=" + empid + ", deptname=" + deptname + ", name=" + name + ", salary=" + salary + '}' + "\n";
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 23 * hash + this.empid;
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Employee other = (Employee) obj;
        if (this.empid != other.empid) {
            return false;
        }
        return true;
    }

    @Override
    public int compareTo(Object o) {
        if (o instanceof Employee) {
            Employee other = (Employee) o;
            return this.name.compareTo(other.name);
        } else {
            throw new RuntimeException("Comparison object is not matching");
        }
    }
}

Requirement: We want to sort Employee objects first by deptname and then followed by employee name within each department.
public class MultipleSort {

    public static void main(String[] args) {
        List emplist = new ArrayList();
        emplist.add(new Employee(353744, "MCA", "Athiruban", 47000));
        emplist.add(new Employee(311344, "CSE", "Nandhini", 41000));
        emplist.add(new Employee(351144, "EEE", "Kishore", 44400));
        emplist.add(new Employee(353321, "MCA", "Karthik", 37000));
        emplist.add(new Employee(353711, "CSE", "Gopal", 37000));
        emplist.add(new Employee(353743, "IT", "AthiNivas", 67000));

        defaultSortandDisplay(emplist);
        sortByDeptAndThenByName(emplist);
    }

    private static void defaultSortandDisplay(List emplist) {
        Collections.sort(emplist);
        System.out.println("DefaultSortandDisplay->\n" + emplist);
    }

    private static void sortByDeptAndThenByName(List emplist) {
        Map> mapSortedByDept = new TreeMap>();
        List finallist = new ArrayList();
        for (Employee e : emplist) {
            if (mapSortedByDept.containsKey(e.getDeptname()) == true) {
                mapSortedByDept.get(e.getDeptname()).add(e);
            } else {
                List templist = new ArrayList();
                templist.add(e);
                mapSortedByDept.put(e.getDeptname(), templist);
            }
        }
        System.out.println("Ordered by Department->\n" + mapSortedByDept);

        Collection> collectionSortedByDept = mapSortedByDept.values();
        for (List indvlist : collectionSortedByDept) {
            Collections.sort(indvlist);
            finallist.addAll(indvlist);
        }
        System.out.println("Ordered by name within Department->\n" + mapSortedByDept);
        System.out.println("Final list->\n" + finallist);
    }
}

Thursday, May 7, 2015

Observer Pattern example



package designpatterns;

/*
 * Observer Pattern example
 */

class WeatherData {

    float temperature;
    float humidity;
    
    public float getTemperature(){
        return temperature;
    }
    
    public float getHumidity() {
        return humidity;
    }
    
    public void setTemperature(float t) {
        temperature = t;
    }
    
    public void setHumidity(float h) {
        humidity = h;
    }
}

/*
 * The below interface adds functionality to add, remove subscribers/clients 
 *  to the internal list so that they can be notified whenever the state of
 *  the weather changes.
 */
 
interface WeatherNotifier {
    public void notify();
    public void addListener(Object client);
    public void removeListener(Object client);
}

/*
 * WeatherData after implementing the above interface
 */

class WeatherData implements WeatherNotifier {
    private List subscribers;
    {
        subscribers = new ArrayList();
    }
    
    public void notify() {
        // notify/wake up all the subscribers to update their view with latest state information
        Iterator iterator = subscribers.iterator();
        while (iterator.hasNext()) {
            iterator.next().update();
        }
    }

    @Override    
    public void addListener(Object client) {
        subscribers.add(client);
    }
    
    @Override
    public void removeListener(Object client) {
        subscribers.remove(client);
    }

   public void setTemperature(float t) {
        temperature = t;
        dataChanged();
    }
    
    public void setHumidity(float h) {
        humidity = h;
        dataChanged();
    }
    
    private void dataChanged() {
        notify();
    }

    public float getTemperature(){
        return temperature;
    }
    
    public float getHumidity() {
        return humidity;
    }

}

interface WeatherReader {
    public void update();
}

class WeatherClient implements WeatherReader{
    WeatherData source;
    
    public void update() {
        System.out.println("Temperature is " + source.getTemperature());
        System.out.println("Humidity is    " + source.getHumidity());       
    }
}

Wednesday, May 6, 2015

Adapter Pattern example

Adapter Pattern

It helps to assign/convert one interface (called as source) to another distinct interface (called as target).

Example Description:

The below code helps us to use legacy Enumeration class available in Vector class in place of modern Iterator class.

package designpattern;

import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;

/**
 *
 * @author DELL
 */
public class AdapterPatternExample {

    public static void main(String[] args) {
        demo();
    }

    public static void demo() {
        Vector namelist = new Vector();
        namelist.add("Athiruban");
        namelist.add("Athinivas");
        Enumeration legacyIterator = namelist.elements();
        Iterator iterator;

        LegacyIteratorAdapter adapter = new LegacyIteratorAdapter(legacyIterator);
        //iterator = legacyIterator;    /* this code will fail */
        iterator = adapter;
        for (; iterator.hasNext();) {
            System.out.println(iterator.next().toString());
        }
    }
}

class LegacyIteratorAdapter implements Iterator {
    /*
     * The purpose of the class to adapt the legacy Enumeration interface to
     * modern Iterator interface.
     */

    Enumeration legacyIterator;

    public LegacyIteratorAdapter(Enumeration e) {
        legacyIterator = e;
    }

    @Override
    public boolean hasNext() {
        return legacyIterator.hasMoreElements();
    }

    @Override
    public Object next() {
        return legacyIterator.nextElement();
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}

Saturday, May 2, 2015

Coding refresher on Github

It gives an immense pleasure to share my technical experience with fellow people. I started pushing all my local code fragments/programs to github as a way of helping young/new programmers on how to code in Java.

Github link to my program list that helped me to attain "Oracle Certified Java Professional".

https://github.com/athiruban/CodingRefresher

Many new interesting topics on DataStructure and Algorithms will be added to the above repo.

Please visit and share your comments on how we can improve this further.

Friday, April 3, 2015

Largest rectangle in a histogram

The below code finds the rectangle with maximum area in a histogram with O(n) time complexity.

    public static void maxRectArea(int a[], int b[]) {
        // this is a maximization problem
        // irrespective of the height of the the next bar
        // we have to compare the area if including next bar exceeds the current area then we have to include the bar.
        // stop the expansion and proceed further until end of input.
        // 6 2 5 4 5  1 6
        // 6 2 5 8 12 1 6
        int i = 0;
        int max = -1;
        int e = 0;

        while (i < a.length) {
            if (i == 0)
                e = b[i] = a[i];
            else {
                if (a[i] < a[i-1]) {
                    int t = b[i-1] / e;
                    if (((t+1) * a[i]) < b[i-1])
                        e = b[i] = a[i];
                    else {
                        e = a[i];
                        b[i] = (t+1) * a[i];    
                    }
                }
                else if (a[i] == a[i-1]) {
                    b[i] = b[i-1] + e;
                }
                else if (a[i] > a[i-1]) {
                    if ((b[i-1] + e) > a[i]) {
                        b[i] = b[i-1] + e;
                    }
                    else {
                        e = b[i] = a[i];
                    }
                }         
            }
            i++;
        }
    }

Sunday, March 8, 2015

Using recursion

//Substring using recursion

substring("", userinput, 0, userinput.length());

public static void substring(String fixed, String str, int step, int len) {

     if (step < len) {

       System.out.printf("%d :%s \n", ++counter, fixed);

       while (step < len) {

         substring(fixed + str.charAt(step), str, step + 1, len);

         step ++;

       }
     }

     else

     System.out.printf("%d :%s \n", ++counter, fixed);

   }

//Anagram using recursion

  public static void anagram(String str, int len) {

    anagram0("", str, len);

  }

  public static void anagram0(String first, String str,

                              int len) {

    String left = "", right = "";

    if (len == 1) {

      System.out.println(":" + first + str);

    }

    else {

      for (int pos = 0; pos < len; pos++) {

        String temp = "" + str.charAt(pos);

        left = str.substring(0, pos);

        if (pos + 1 == len)

          right = "";

        else

          right = str.substring(pos + 1, len);

        anagram0(first + temp, left + right, len - 1);

      }

    }

  }