Tuesday, 28 February 2017

What is initial capacity and load factor?


Initial capacity is nothing but the number of buckets when the hash table is created, capacity is automatically increased when hash table get full of element.

Load factor is a measurement of how full collection (hash table) is allowed to get before its capacity is automatically increased. When the number of entries in the hash table exceeds the product of the load factor and the current capacity, the hash table is rehashed (that is, internal data structures are rebuilt) so that the hash table has approximately twice the number of buckets.

How it affects performance?
As a general rule, the default load factor (.75) offers a good trade-off between time and space costs. Higher values decrease the space overhead but increase the lookup cost (reflected in most of the operations of the HashMap class, including get and put). The expected number of entries in the map and its load factor should be taken into account when setting its initial capacity, so as to minimize the number of rehash operations. If the initial capacity is greater than the maximum number of entries divided by the load factor, no rehash operations will ever occur.

Conclusion:
So finally we can conclude default load capacity (.75) used by Hash Map is a good value in most situations. We can set the initial capacity of Hash Map based on own knowledge of how many items it will hold.

Set it like, initial-capacity = number of items/.75 (round up).


Generate the next prime of a number in Java

Java java.math.BigInteger class contains a method nextProbablePrime () to check the primality of a number.

import java.math.BigInteger;

public class NextPrime {

            public static void main(String[] args) {
                        int number = 83;
                        Long nextPrime = nextPrime(number);
                        System.out.println(nextPrime + " next prime to " + number);

            }

            /**
             * method to find next prime
             * @param number
             * @return boolean
             */
            private static Long nextPrime(int number) {
                        BigInteger bValue = BigInteger.valueOf(number);
                       
                        /**
                         * nextProbablePrime method used to generate next prime.
                         * */
                        bValue = bValue.nextProbablePrime();
                       
                        return Long.parseLong(bValue.toString());
            }
}

Output:
            89 next prime to 83

Why wait(), notify() and notifyAll() are in Object class and not in Thread class in java?


1. These method not only used for synchronization, but also they can be used for communication between two threads and Object class is correct place to make them available for every object if this mechanism is not available via any java keyword like synchronized.

Point to remember: Synchronized is used to provide mutual exclusion and ensuring thread safety of Java class like race condition. However wait, notify and notifyAll can be used for communication mechanism among threads.

2. Every Object has a monitor, acquiring that monitors allow thread to hold lock on object (=Locks are made available on per Object basis), which is another reason wait and notify is declared in Object class rather than Thread class.

3. wait(), notify() and notifyAll() are called on objects only When wait() method is called on object by thread it waits for another thread on that object to release object monitor by calling notify() or notifyAll() method on that object.
When notify() method is called on object by thread it notifies all the threads which are waiting for that object monitor that object monitor is available now.
So, this shows that wait(), notify() and notifyAll() are called on objects only.

4. As multiple threads may request to access the same object at a time. However only thread can hold object monitor at a time. As a result thread can notify other threads of same object that lock is available now. But, put these method into thread does not make any sense because multiple threads exists on object it's no other way around (i.e. multiple objects exists on thread).


Hypothetical scenario:
Suppose, Thread class contains wait(), notify() and notifyAll() methods?
Having wait(), notify() and notifyAll() methods means Thread class must have their monitor i.e. every thread having their monitor will create few problems:

Thread communication problem

Synchronization on object won’t be possible- Because object has monitor, one object can have multiple threads and thread hold lock on object by holding object monitor. But if each thread will have monitor, we won’t have any way of achieving synchronization.

Inconsistency in state of object (=synchronization won't be possible).


Monday, 27 February 2017

Comparable vs. Comparator

Comparable: java.lang
Comparator: java.util

1) It provides single sorting sequence.

We can sort on particular single scenario.

It provides multiple sorting sequences.

We can provide different comparator to sort.

2) Comparable affects the original class i.e. actual class is modified.

Comparator doesn't affect the original class i.e. actual class is not modified.
3) Comparable provides compareTo() method to sort elements.
Comparator provides compare() method to sort elements.

4) We can sort the list elements of Comparable type by Collections.sort(List) method.
We can sort the list elements of Comparator type by Collections.sort(List,Comparator) method.




package com.comparator;
import java.util.Comparator;
public class StringComparator implements Comparator<String>{

       @Override
       public int compare(String objStr1, String objStr2) {
              int result = 0;
              if(objStr1!=null && objStr2!=null) {
                     result = -1 * objStr1.compareTo(objStr2);
              }
              return result;
       }
}

package com.comparator;
import java.util.Map;
import java.util.TreeMap;
public class TestComparator {
       public static void main(String[] args) {
             
              /**
               * Default Sorting accoding to comparable implemetation of
               * string class in ascending order.
               */
              Map<String,String> map = new TreeMap<String,String>();
              map.put("A""1");
              map.put("B""2");
              map.put("C""3");
             
              System.out.println(map);
             
              /**
               * Using external comparator sort String keys in descending order.
               */
              StringComparator comparator = new StringComparator();
              Map<String,String> compMap = new TreeMap<String,String>(comparator);
              compMap.put("A""1");
              compMap.put("B""2");
              compMap.put("C""3");
             
              System.out.println(compMap);
       }
}

Output:
{A=1, B=2, C=3}
{C=3, B=2, A=1}

Friday, 17 February 2017

Interface-segregation principle


What is the point in selling a horse saddle for one who does not own a horse?

The interface segregation principle (ISP) states that no client should be forced to depend on methods it does not use. ISP splits interfaces that are very large into smaller and more specific ones so that clients will only have to know about the methods that are of interest to them.

Clients should not be forced to depend upon methods that they don't use.



ISP is intended to keep a system decoupled and thus easier to refactor, change, and redeploy.

When we design an application we should take care how we are going to make abstract a module which contains several submodules. Considering the module implemented by a class, we can have an abstraction of the system done in an interface. But if we want to extend our application adding another module that contains only some of the sub-modules of the original system, we are forced to implement the full interface and to write some dummy methods. Such an interface is named fat interface or polluted interface. Having interface pollution is not a good solution and might induce inappropriate behavior in the system.



//interface segregation principle - bad example
interface IWorker {
    
     public void work();
     public void eat();
}

class Worker implements IWorker {
     public void work() {
           // ....working
     }
     public void eat() {
           // ...... eating in lunch break
     }
}

class Robot implements IWorker {
     public void work() {
           //.... working much more
     }

     /** Dummy implementation while robot will not eat lunch.*/
     public void eat() {
           //.... eating in lunch break
     }
}

class Manager {
     IWorker worker;

     public void setWorker(IWorker w) {
           worker=w;
     }

     public void manage() {
           worker.work();
     }
}

If the design is already done fat interfaces can be segregated using the Adapter pattern.



// interface segregation principle - good example
interface IWorker extends IFeedable, IWorkable {
}

interface IWorkable {
     public void work();
}

interface IFeedable{
     public void eat();
}

class Worker implements IWorkable, IFeedable {
     public void work() {
           // ....working
     }

     public void eat() {
           //.... eating in lunch break
     }
}

class Robot implements IWorkable {
     public void work() {
           // ....working
     }
}

class Manager {
     IWorker worker;

     public void setWorker(IWorker w) {
           worker=w;
     }

     public void manage() {
           worker.work();
     }
}

Related Posts Plugin for WordPress, Blogger...