Wednesday, November 18, 2015

Why Override equals, hashcode and toString method in Java

 Why you should override equals and hashcode ?
 
 equals() is used to check if two objects are equal or not. Now this equality can be defined in two ways, identity equality and logical equality. it's the logical equality, which is taken care by equals method. Every class in Java implicitly inherit from java.lang.Object, and from there every object inherit equals() and hashcode(). There default implementation is in line with == operator, i.e. equals() provide identity equality and return true if reference variable pointing to same object. Now, if you don't need logical equality, then you don't need to override equals, but the problem is you will need it. All your domain object e.g. Order, Trade, Message can be compared to each other and you need logical comparison. One of the popular example is java.lang.String class, which needs logical comparison i.e. character based comparison. If two String object contains same characters in same order they are considered equals, which is what you need in many programming task. Similarly, all domain object has equality defined, but true need of equals and hashcode arise, when you use them as key in hash based collection e.g. Hashtable or HashMap. These collection classes relies on rules of  Java programming around equals and hashcode to work according to their specification, popularly known as equals-hashcode contract. According to which, you must override hashcode, if you are overriding equals and vice-versa. Problem is that this is not enforced by compiler, and if you make such mistake, your program will not work properly.

For example, any object which doesn't follows equals and hashcode contract, if used as key in HashMap, you may not be able to retrieve object again, see how HashMap works internally in Java for more details. In short, you need to override equals and hashcode, if you are writing a domain object, or you want to store them in hash based collection. Once you understand why you should override equals and hashcode, and when you should do that, it's easy to actually do that.


Why you need to override toString method

You should override toString() method for all domain object, because whenever you print them using logger or System.out.println() statements, there toString() method is called. Since default implementation of toString() is not very helpful, and only print classname@hashcode e.g. com.mine.ready@709903.

How to use Future and FutureTask in Java Concurrency

Future and FutureTask in Java allows you to write asynchronous code. Future is a general concurrency abstraction, also known as promise, which promises to return a result in future. In asynchronous programming, main thread doesn't wait for any task to finished, rather it hand over the task to workers and move on. One way of aynchronous processing is using callback methods. Future is another way to write asynchronous code. By using Future and FutureTask, you can write method which does long computation but return immediately. Those method, instead of returning result, return a Future object. You can later get result by calling Future.get() method, which will return object of type T, where T is what Future object is holding . One example of Future is submit() method of ExecutorService, which immediately return a Future object. By the way, Future and FutureTask are available in java.util.concurreent package from Java 1.5. Also, Future is and interface and FutureTask is an implementation or RunnableFuture, which can be used as Runnable interface, thus, can be passed to ExecutorService. In this Java concurrency tutorial, we will learn how to use Future and FutureTask in Java.



Future and FutureTask Example - Java
 
One of the simplest example of using Future is working with Thread pools. When you submit a long running task to ExecutorService, it returns a Future object immediately. This Future object can be used to query task completion and getting result of computation. In our sample Java program, we have a created a FactorialCalculator task, which wraps calculation of factorial under Callable interface's call() method. When we submit this task with job of calculating factorial of huger number like 100000, ExecutorService returns a Future object, which holds long value, return type of call method in our case. Later, we check whether task is completed or not using isDone() method. From output, you can see that main thread returns immediately. Since we have used get() method once task is completed, it doesn't block and return result immediately. By the way, Future object returned by submit() method is also an instance of FutureTask.

 Important points Future and FutureTask  in Java

1. Future is base interface and define abstraction of object which promises result to be available in future, while FutureTask is an implementation of Future interface.
2. Future is a parametric interface and type-safe written as Future, where V denotes value.
3. Future provides get() method to get result, which is blocking method and blocks until result is available to Future.
4. Future interface also defines cancel() method to cancel task.
5. isDone() and isCancelled() method is used to query Future task states. isDone() returns true if task is completed and result is available to Future. If you call get() method, after isDone() returned true then it should return immediately. On the other hand, isCancelled() method returns true, if this task is cancelled before its completion.
6. Future has four sub interfaces, each with additional functionality e.g. Response, RunnableFuture, RunnableScheduledFuture and ScheduledFuture. RunnableFuture also implements Runnable and successful finish of run() method cause completion of this Future.   
7. FutureTask and SwingWorker are two well known implementation of Future interface. FutureTask also implements RunnableFuture interface, which means this can be used as Runnable and can be submitted to ExecutorService for execution.
8. Though most of the time ExecutorService creates FutureTask for you, i.e. when you submit() Callable or Runnable object. You can also created it manually.
9. FutureTask is normally used to wrap Runnable or Callable object and submit them to ExecutorService for asynchronous execution.

Constructor vs Init method in Servlet

Servlet implementation classes can have constructor but they should be using init() method to initialize Servlet because of two reasons, first you cannot declare constructors on interface in Java, which means you cannot enforce this requirement to any class which implements Servlet interface and second, Servlet require ServletConfig object for initialization which is created by container as it also has reference of ServletContext object, which is also created by container.

Servlet is an interface defined in javax.servlet package and HttpServlet is a class and like any other class in Java they can have constructor, but you cannot declare constructor inside interface in Java. If you don't provide an explicit constructor than compiler will add a default no argument constructor in any Servlet implementation class. Another reason that you should not initialize Servlet using constructor because Servlets are not directly instantiated by Java code, instead container create there instance and keep them in pool. Since containers from web servers like Tomcat and Jetty uses Java Reflection for creating instance of Servlet, presence of no argument constructor is must. So, by any chance if you provide a parametric constructor and forget to write a no argument constructor, web container will not be able to create instance of your Servlet, since there is no default constructor. Remember Java compiler doesn't add default no argument constructor, if there is a parametric constructor present in class. That's why it's not advised to provide constructor in Servlet class. Now let's see some difference between Constructor and init method in Java Servlet



Difference between Constructor and init method in Servlet ?
 
In real world application, you better use init() method for initialization, because init() method receives a ServletConfig parameter, which may contain any initialization parameters for that Servlet from web.xml file. Since web.xml provides useful information to web container e.g. name of Servlet to instantiate, ServletConfig instance is used to supply initialization parameter to Servlets. You can configure your Servlet based upon settings provided in ServletConfig object e.g. you can also provide environment specific settings e.g. path of temp directory, database connection parameters (by the way for that you should better leverage JNDI connection pool) and any other configuration parameters. You can simply deploy your web application with different settings in web.xml file on each environment. Remember, init() method is not chained like constructor, where super class constructor is called before sub class constructor executes, also known as constructor chaining.


Difference between HashMap, LinkedHashMap and TreeMap in Java

if you are looking to store key value pairs in Java program,  you have wide range of choices available depending upon your requirement. Main difference between LinkedHashMap, TreeMap and HashMap comes in there internal implementation and specific features, which makes them useful in certain scenarios. For example, HashMap is a general purpose Map (hash table data structure), which should be used whenever you need a hashing based data structure for storing your mappings (key value pairs). TreeMap provides you sorting, on top of hashing offered by Map interface, which means you can not only retrieve elements in constant time i.e. O(1) time, but also iterate through those mapping in a predefined sorted order, but you need to pay heavy price to keep mappings in sorted order. On the other hand, LinkedHashMap is a compromise between these two, it doesn't provide sorting but unlike HashMap, it provides ordering e.g. maintaining mappings in a order they are inserted into Map, known as insertion order or order on which they are accessed, called access order. Apart from these three popular Map implementation, you also have some special purpose Map implementations e.g. EnumMap for storing mapping with enum constants as keys,  it is highly optimized for enum constants. You also have a special map called WeakHashMap for creating a Garbage Collector friendly Cache, where values become eligible for garbage collection as soon as there is no other reference to them apart from keys in WeakHashMap.Then there is IdentityHashMap for creating a Map which uses identity instead of equality for comparing keys, since identity equality is rare, you get less number of collision on this Map and finally JDK 5 introduced ConcurrentHashMap for better scalability in multi-threaded environment, wher When to use LinkedHashMap, TreeMap and HashMap in Java

You can use a LinkedHashMap, when you need to keep your mappings in either insertion order or access-order. LinkedHashMap by default keeps elements in the order, on which they are inserted, and this order is reflected when you traverse over LinkedHashMap, but it also provides a constructor, which allows you to keep entries in access-order, i.e. order in which they are accessed. One of the clever use of Java LinkedHashMap is to use it as Least Recently Use or LRU Cache.

TreeMap is your go to map implementation if you want to keep keys  in a sorted order, either in there natural order defined by Comparable interface or a custom order imposed by Comparator interface, though it's worth remembering that your compareTo() or compare() method must be consistent with equals() method, because Map interface is defined in terms of equals and TreeMap uses compareTo for comparing keys. So if keys compare() or compareTo() implementation is not consistent, then it will fail to obey Map's general contract.

HashMap is your general purpose hashing based collection, whenever you need to use a hash table data structure in Java to store key value pairs, first choice goes to HashMap in single threaded environment. If you happened to use a Map in a multi-threaded environment consider using Hashtable, synchronized HashMap or ConcurrentHashMap from Java Collection Framework.

Since LinkedHashMap solved problem of chaotic ordering provided by Hashtable and HashMap, without incurring high cost associated with TreeMap, you can also used LinkedHashMap to create a copy of a Map in Javae number of reader threads clearly out numbers number of writer threads.

Difference between Primitive and Reference variable in Java

There are two types of variables in Java, primitive and reference type. All the basic types e.g. int, boolean, char, short, float, long and double are known as primitive types. JVM treats them differently than reference types, which is used to point objects e.g. String, Thread, File and others. Reference variables are not pointers but a handle to the object which are created in heap memory. Main difference between primitive and reference type is that, primitive type always has a value, it can never be null but reference type can be null, which denotes absence of value. So if you create a primitive variable of type int and forget to initialize it then it's value would be 0, the default value of integral type in Java, but a reference variable by default has null value, which means no reference is assigned to it. If you try to access any field or invoke a method on null reference, you will be greeted with NullPointerException in Java. It's very important for every Java developer to understand difference between primitive and reference variable in different cases e.g. while assigning values, comparing values, passing them as method arguments and returning them from methods, to avoid nasty errors e.g. null pointer exception. In short, main difference between two types is that primitive types stores actual values but reference type stores handle to object in heap

Passing primitive and reference variable as method argument
 
When you pass primitive values to a method the values are passed to method, but when you pass reference variable, only handle is copied. which means for primitives, changing the formal parameter's value doesn't affect the actual parameter's value, while in case of reference types, changing the formal parameter's handle doesn't affect the actual parameter's address but changing the formal parameter's internal values does affect actual parameter's object, because they refer to same object in memory.