Thursday, 26 November 2015

Why Key of a Map must be Immutable ?

Immutable Object :
An immutable object is a special kind of object whose state can not be changed once it is created. These objects are used in concurrent applications as the states can not be changed, So there is no question of corrupting the state by thread interference. And one more major use is while working with java.util.Map the key must be an immutable object. Else once you have added one entry to the map and after that if the state of the key got changed then you will lose the object mapping.

Example:
class User {
    String email;
    String name;
    public User(String email, String name) {
        this.email = email;
        this.name = name;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        if (!email.equals(user.email)) return false;
        return name.equals(user.name);
    }
    @Override    public int hashCode() {
        int result = email.hashCode();
        result = 31 * result + name.hashCode();
        return result;
    }
}
public class ImmutableKeyTest {
    public static void main(String[] args) {
        Map<User, String> userDealMap = new HashMap<>();
        User user = new User("abc@gmail.com", "ABC");
        User user1 = new User("xyz@gmail.com", "XYZ");
        userDealMap.put(user, "HAPPY50");
        userDealMap.put(user1, "HAPPY25");
        System.out.println(userDealMap);

        System.out.println("Before Key Change");
        System.out.println(userDealMap.get(user));
        user.setName("ABC DEF");
        System.out.println("After Key Change");
        System.out.println(userDealMap.get(user));
    }
}
Output: {User@b42dca6f=HAPPY25, User@4a84e2cf=HAPPY50} Before Key Change HAPPY50 After Key Change null Here when the name of the user got changed, it impacts the hashCode of the user object, so while getting the value from the map, it treats the supplied key as a new key and returns NULL.

Solution: Solution is very simple ! Make the User object as immutable object. (Guideline for creating immutable object refer https://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html)

final class User {
    final String email;
    final String name;
    public User(String email, String name) {
        this.email = email;
        this.name = name;
    }
    public String getEmail() {
        return email;
    }
    public String getName() {
        return name;
    }
    @Override    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        if (!email.equals(user.email)) return false;
        return name.equals(user.name);
    }
    @Override    public int hashCode() {
        int result = email.hashCode();
        result = 31 * result + name.hashCode();
        return result;
    }
}
Once you make it immutable, you can not change the state of the object by any chance.
// user.setName("ABC DEF"); // This will give compilation error as no setter method there

Tuesday, 24 November 2015

Know LinkedHashMap in Depth

LinkedHashMap is a map which extends HashMap class and implements Map interface. But the only different between LinkedHashMap and HashMap is LinkedHashMap maintains the insertion order whereas HashMap doesn't. LinkedHashMap uses double LinkedList internally to maintain the order.

Example :

class Employee{
    String id;
    String name;
    public Employee(String id, String name) {
        this.id = id;
        this.name = name;
    }
    @Override    public String toString() {
        return "["+id+","+name+"]";
    }
}

import java.util.HashMap;
import java.util.LinkedHashMap;

public class LinkedHashMapDemo1 {
    public static void main(String[] args) {
        LinkedHashMap<Employee, Integer> linkedMap = new LinkedHashMap<>();
        HashMap<Employee, Integer> hashMap = new HashMap<>();

        System.out.println("LinkedHashMap : ");
        linkedMap.put(new Employee("1001","Alpha"), 2000);
        linkedMap.put(new Employee("1002","Beta"), 2000);
        linkedMap.put(new Employee("1003","Gama"), 2000);
        System.out.println(linkedMap);

        System.out.println("HashMap : ");
        hashMap.put(new Employee("1001","Alpha"), 2000);
        hashMap.put(new Employee("1002","Beta"), 2000);
        hashMap.put(new Employee("1003","Gama"), 2000);
        System.out.println(hashMap);
    }
}
Output:
LinkedHashMap : 
{[1001,Alpha]=2000, [1002,Beta]=2000, [1003,Gama]=2000}
HashMap : 
{[1001,Alpha]=2000, [1003,Gama]=2000, [1002,Beta]=2000}

Here LinekedHashMap keeps the insertion order but HashMap doesn't.

Now the Secret of LinkedHashMap :

LinkedHashMap provided a special constructor to maintain access order instead insertion order. public LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder) Access Order is like maintaining the order of the entries accessed. Access Order is affected by get(key), put(key,val) and putAll(Map). Because of this nature, LinkedHashMap is used in LRU(Least Recent Used) Caching.
Example: 
import java.util.LinkedHashMap;
import java.util.Map;
public class LinkedHashMapTest {
    public static void main(String[] args) {
        LinkedHashMap<String, Integer> linkedMap = new LinkedHashMap<>();
        System.out.println("Default LinkedHashMap : ");
        linkedMap.put("Gama", 2000);
        linkedMap.put("Alpha", 2000);
        linkedMap.put("Beta", 2000);
        // Once Added after that no change in order
        linkedMap.put("Alpha", 3000);
        linkedMap.put("Beta", 3000);
        linkedMap.put("Gama", 3000);
        linkedMap.get("Alpha");
        linkedMap.get("Beta");
        System.out.println(linkedMap);

        // LinkedHashMap with accessOrder        
        System.out.println("LinkedHashMap with accessOrder  = TRUE: ");
        LinkedHashMap<String, Integer> linkedAccessedOrderMap = 
                        new LinkedHashMap<>(10, 0.5f, true);
        linkedAccessedOrderMap.put("Gama", 2000);
        linkedAccessedOrderMap.put("Alpha", 2000);
        linkedAccessedOrderMap.put("Beta", 2000);
        linkedAccessedOrderMap.put("Alpha", 3000);
        linkedAccessedOrderMap.get("Gama");
        System.out.println(linkedAccessedOrderMap);
    }
}
Output:
Default LinkedHashMap : 
{Gama=3000, Alpha=3000, Beta=3000}
LinkedHashMap with accessOrder  = TRUE: 
{Beta=2000, Alpha=3000, Gama=2000}

Monday, 23 November 2015

Secrets of java.lang.ThreadLocal - Part I

java.lang.ThreadLocal is given by Java API to achieve the thread-safety in multi-threaded environment. Unlike of synchronization or locking this eliminates the sharing concept rather maintains an individual copy of object for each thread. So no need of locking or synchronization which results more scalability and performance.


Output:
Here id and threadLocal both are shared resources but ThreadLocal maintains individual copy for each thread.

Now the Secret of ThreadLocal is
- Each Thread object contains an instance member variable as ThreadLocal.ThreadLocalMap threadLocals;
- Where as ThreadLocal.ThreadLocalMap contains array of entries of java.lang.ref.Reference type as private Entry[] table;
And this Entry is a simple <key, value> pair like Map.Entry which contains ThreadLocal<?> as key and Object as value
- ThreadLoacl class has 2 important methods 
public void set(T value) : while setting the value, it first gets the ThreadLocalMap of the current thread. Then adds an entry with <this ThreadLocal object, passed Value>
* public T get() : while getting the value, first gets the ThreadLocalMap of the current thread. Then get the value for the Entry by passing key as this current ThreadLocal object. If not found any value then sets and returns the initial value provided by the programmer. 
ThreadLocal class having a callback method to provide the initial value as protected T initialValue(); ]

To provide initial value we can override callback method as below :
ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>() {
    @Override    protected Integer initialValue() {
        return 100;
    }
};






Sunday, 22 November 2015

Use Non-final variable inside Anonymous Inner Class

Accessing local variable inside an inner class need to be declared as final or effectively final(this is new in Java 8). 

But if we have a requirement of changing that variable after inner class then we can't declare the local variable as final. So to use that non-final local variable effectively inside inner class we can pass that variable as constructor argument to that inner class and use it.

Example : 

class IdGenerator {
    long id = 99990000;

    public IdGenerator() {
    }

    public String generateId() {
        return String.valueOf(++id);
    }
}

interface Service {
    void logData();
}
public class InnerClassWithNonFinalVariable {
    public static void main(String[] args) {
        IdGenerator idGenerator = new IdGenerator();

        class MyService implements Service {
            private IdGenerator generator;

            MyService(IdGenerator generator) {
                this.generator = generator;
            }

            @Override            public void logData() {
                System.out.println("Logging Data :" + this.generator.generateId());
            }
        }

        Service service = new MyService(idGenerator);
        service.logData();

        /* Using idGenerator for some other purpose */        idGenerator = null;
    }
}

But while working with Anonymous Inner Class, We don't have option to define constructor. So below demonstrated code shows how to use non-final local variable inside anonymous inner class.



Saturday, 7 November 2015

Use Varargs Carefully !

So, what are the things need to take care while using varargs in Java ?
Let's take a simple example : 
public static int findMax(int... numbers) {
    int max = numbers[0];
   
for (int i = 1; i < numbers.length; i++) {
       
if (numbers[i] > max)
            max = numbers[i];
    }
   
return max;
}
findMax(1, 2, 3, 4, 5); // 5
findMax(10, 2, 30, 4, 50, 6); // 50
findMax(3); // 3

Here this above code looks good and the findMax() method works fine. But the problem here is in run time it will fail with specific inputs like :
findMax(null); // Exception in thread "main" java.lang.NullPointerException
findMax(); // Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0

Because here the code expects at least one value.
So to avoid these problems we can modify the method in such way like :
public static int findMax(int... numbers) {
    if (numbers == null || numbers.length == 0)
       
throw new IllegalArgumentException("At least one input required.");
   
int max = numbers[0];
   
for (int i = 1; i < numbers.length; i++) {
       
if (numbers[i] > max)
            max = numbers[i];
    }
   
return max;
}

But here we need extra code:
#1. one more validation required
#2. the calling method need to be more cautious to handle "IllegalArgumentException"
Instead of all above resolution we can handle this problem in a shorter and smarter way by using the varargs in proper way.

public static int findMax(int firtNumber, int... numbers) {
   
int max = firtNumber;
   
for (int i = 0; i < numbers.length; i++) {
       
if (numbers[i] > max)
            max = numbers[i];
    }
    
return max;
}
Here we have made the first number as a separate parameter, So the compiler will not allow to invoke method by passing null or empty arguments like  findMax(null) and findMax().

Wednesday, 30 September 2015

Java Doesn't Support Pass By Reference

Pass By Value vs Pass By Reference

Pass By Value :  In pass by value, the copy of the value of the argument passed from calling method and the parameter of the called method receives that value. Since it just a copy so any changes to the parameter inside called method doesn't reflect to the argument of the calling method.

Pass By Reference : In this case, the address of the argument is passed instead of value and the parameter of the called method receives that address like thought pointer in C. 

But in Java there is no concept of Pointers. Since both the argument and parameter are references one can't hold the address of another rather holds the value of another reference. So every thing in Java is Pass By Value even though both are references.

Example of Proof : 



OutPut: 






Inside Memory :

Monday, 28 September 2015

Secret of Spring AOP.

How AOP works internally ? 

Here we will discuss on logging functionality as one of the AOP usages. Here I have implemented a POC using Java core API to demonstrate similar as Spring AOP functionality.

Prerequisite : Java Core Proxy API, Reflection API and Annotation API (java.lang.reflect, java.lang.annotation  packages)

Secret : Here also the main secrets are proxy object, MethodHandler, reflection and annotation. But the method handler class is main secret player of our discussion, which has the full controller on the proxy objects and when any method call happened on a proxy object it passes through the this handler. Inside the call back method of the handler, using reflection it introspects all the applied annotations and based on that it generates required log statements.


For more about Proxy object/Reflection API/MethodHandler, Please refer to my previous blog
http://secretsinjava.blogspot.in/2015/09/secret-of-spring-jpa-repository.html

Annotation API : Annotations are nothing but meta information about a program element like class, method, variables. Java API having so many built-in annotations but we can define our own custom annotation as well.

In this context using our custom annotations we will enable the logging functionality such that for every method call, based on the applied annotation the log statement will generate. Log statement can be before method call or after method call or on exception.


Source Code :
Annotations: Here We have created some annotations to annotate the method for which we want to generate the log


Worker.java
Here in WorkerController class, WorkerService field is assigned with proxy object, where as in Spring it will be auto wired by Spring Container.
AOPLoggingMethodHandler.java
 
Here in Main class also, WorkerController field is assigned with proxy object, where as in Spring it will be auto wired by Spring Container.
Output:



Thanks you for visiting the page. Please feel free to provide your precious suggestions and comments. 






Saturday, 26 September 2015

Secret of Spring JPA Repository

Here we will discuss on how Spring JPA Repository works. 
We will mainly focus on below couple of things : 
1.  How Spring provides Proxies for repositories 
2.  How Spring resolves the repository method name when there is no JPQL provided 

Before we start we need to know about some Java core API like Reflection and Proxy of (java.lang.reflect) package

Reflection API : Using this we can introspect any class and can create instance in run time and invoke any method of that instance. In a single line, we can have full control and information of that object.
Proxy API : Hep of this we can create proxy instance of any class and so that we can have full control of any method invocation. But here I am using javaassist library API for proxy creation since it has more flexibility than the core API

Secret : Here the secret is while creating proxy instance of any class the proxy API expects one MethodHandler. MethodHandler is nothing just an interface contains a call back method for which we have to provide the implementation of the method. 
The call back method supplies the parameters like
- the instance on which method invoked
- Method reference to the overridden method declared in the super class or interface.
- Method reference to the forwarder method for invoking the overridden method.  It is null if the overridden method is abstract or declared in the interface.
- arguments passed in the method invocation on the proxy instance
Object invoke(Object self, Method thisMethod, Method proceed,
              Object[] args) throws Throwable; 

Here if the method is abstract then the proceed method reference will be passed to the call back method as NULL. Then we can implement our logic to do what we want. Spring also does in the same way. It resolves the method name and do the required action. Based on the method name it fetches the entity(s) and returned back to the caller object of the repository. 
Source Code :
Egineer.java (Entity class)

 EngineerRepository.java

 Utils.java (To create list of static entities instead of taking fro DB and stores in PersistenceUnit class)

PersistenceUnit.java (Which holds list of static entities and help to fetch required entities on query)
EngineerRepoHandler.java (This is the secret class for handling all repository method invocation)
MyProxyFactory.java (Factory class returns the proxy of a class or an interface using javassist library)
SpringDataRepositoryPOC.java (Main class)

Output:

Please feel free to comment or suggest.



Secret of anonymous inner class

Why the method local variable access within inner class needs to be final or effectively final?

How Inner class access the variable of its enclosing class :
  • instance variable :  All inner class contains an internal reference of its enclosing outer class. Using this reference it access the instance variable of the outer class.
  • static/class variable : It is quite straight forward; it uses the class name directly to access the static variables
  • method local variable : This is the place where the inner class does not have any reference to the local variable since the local variables are created inside stack memory area in JVM. So the outer and inner class have an agreement that any method local variable accessed inside inner class are not going to be modified in future by declaring as final.If the local variable is not declared as final but not modified once it is assigned with the initial value, then that variable is known as effectively final. This time the inner class have the individual copy of local variables those are accessed inside inner class and which will not allow to to modify those variables at any cost.
Example Source Code : 
Compiled Inner class Code : 

Secret of Collections.sort()

How java.util.Collections.sort(List<T> list) works ?

Preface : 
  • All implementation class of List interface overrides toArray() method which returns an array of elements of that list. Except LinkedList all other list holds elements as a form of array internally. Only LinkedList holds in form of linked nodes (not in array form). 
  • List.toArray()
    • LinkedList iterates the linked nodes and store each node into a new array and returns the same
    • Other List implementation classes return a copy of the array that holds the element
  • Collections.sort():
    • sorts the array using Arrays.sort(Object[] a) which uses merge sort algorithm internally to sort the supplied array
    • then using ListIterator of the supplied list, it updates the elements from the sorted array

public static <T extends Comparable<? super T>> void sort(List<T> list) {
    Object[] a = list.toArray(); // Gets array here
    Arrays.sort(a); // Sorting array here
    ListIterator<T> i = list.listIterator();
    for (int j=0; j<a.length; j++) {
        i.next();
        i.set((T)a[j]);  // Updating list here
    }
}
Similarly it uses Arrays.sort(T[] a, Comparator<? super T> c) method when comparator is supplied