Showing posts with label collections. Show all posts
Showing posts with label collections. Show all posts

Tuesday, 2 October 2018



  • How to create Immutable List in java?
    • Once your lis has been initialized, you can do
    • list = Collections.unmodifiableList(list);
  • Why ConcurrentHashMap does not allow null keys and null values ?
    • We all know that ConcurrentHashMap (optimized version of  Hashtable) doesn't allow null key or null values. 
    • The reason behind this implementation is due to ambiguity nature of the ConcurrentMap (ConcurrentHashMap & ConcurrentSkipListMaps) when it comes to multithreading environment. 
    • The main reason is that if map.get(key) returns null, we can't detect whether the key explicitly maps to null vs the key isn't mapped.
    • In ConcurrentHashMap, It might be possible that key 'K' might be deleted in between the get(k) and containsKey(k) calls.
    • if (concurrentHashMap.containsKey(k)) { return concurrentHashMap.get(k); } else { throw new KeyNotPresentException(); }
    • The above example i am  explaining with two thread(1 & 2). In Line 2, after checking thread 1 with the key "K" in concurrentHashMap(Line 1 -contains some value for the key "K"),  it will returns null (if thread 2 removed the key 'K' from concurrentHashMap). Instead of throwing KeyNotPresentException , it actually returns null.
    • As a result, the code will return null as opposed to KeyNotPresentException (Expected Result if key is not present).
  • When to use ConcurrentHashMap in Java?
    • ConcurrentHashMap is best suited when you have multiple readers and few writers
    • If writers greater than readers, or writer is equal to reader, then performance of ConcurrentHashMap effectively reduces to synchronized map or Hashtable.
    •  Performance of CHM drops, because you got to lock all portion of Map, and effectively each reader will wait for another writer, operating on that portion of Map. 
    • ConcurrentHashMap is a good choice for caches, which can be initialized during application start up and later accessed my many request processing threads.
    •  As javadoc states, CHM is also a good replacement of Hashtable and should be used whenever possible, keeping in mind, that CHM provides slightly weeker form of synchronization than Hashtable.
  • How to design a good key for HashMap?
    • If a key()  is overridden  then the corresponding hashcode() must be overridden.
    • Key’s hash code is used primarily in conjunction to its equals() method, for putting a key in map and then searching it back from map. So if hash code of key object changes after we have put a key-value pair in map, then its almost impossible to fetch the value object back from map. It is a case of memory leak. To avoid this, map keys should be immutable. These are few things to create an immutable of class.
    • This is the main reason why immutable classes like String, Integer or other wrapper classes are a good key object candidate.
  • Difference between HashMap and ConcurrentHashMap
    • In concurrentHashMap, the difference lies in internal structure to store these key-value pairs. ConcurrentHashMap has an addition concept of segments. It will be easier to understand it you think of one segment equal to one HashMap [conceptually]. A concurrentHashMap is divided into number of segments [default 16] on initialization. ConcurrentHashMap allows similar number (16) of threads to access these segments concurrently so that each thread work on a specific segment during high concurrency.
    • This way, if when your key-value pair is stored in segment 10; code does not need to block other 15 segments additionally. This structure provides a very high level of concurrency.
  • Difference between HashMap and Collections.synchronizedMap(HashMap)?
    • Sunchronized hash map can be accessed by only one thread at a time.
  • Difference between ConcurrentHashMap and Collections.synchronizedMap( HashMap )?
    • ConcurrentHashMap is consist of internal segments which can be viewed as independent HashMaps, conceptually. All such segments can be locked by separate threads in high concurrent executions. In this way, multiple threads can get/put key-value pairs from ConcurrentHashMap without blocking/waiting for each other.
    • In Collections.synchronizedMap(), we get a synchronized version of HashMap and it is accessed in blocking manner. This means if multiple threads try to access synchronizedMap at same time, they will be allowed to get/put key-value pairs one at a time in synchronized manner.
  • Difference between HashTable and Collections.synchronized(HashMap)?
    • Both are synchronized version of collection. Both have synchronized methods inside class. Both are blocking in nature i.e. multiple threads will need to wait for getting the lock on instance before putting/getting anything out of it.
    • So what is the difference. Well, NO major difference for above said reasons. Performance is also same for both collections.
    • Only thing which separates them is the fact HashTable is legacy class promoted into collection framework. It got its own extra features like enumerators.
  • How to convert an array of String to arraylist?
  • String[] words = {“RAKESH”, “RAVI”,”AZAR”}; List wordList = Arrays.asList(words); //Now you can iterate over the list
  • How to reverse the list?
  • Collections.reverse(list);
  • Can a null element added to a TreeSet or HashSet?
    • Yes
    • A null element can be added only if the Set contains one element,  because when a second element is added then as per set definition a check is made to check duplicate value and comparison with null element will throw NullPointerException.
  • What are IdentityHashMap and WeakHashMap?
    • IdentityHashMap is similar to HashMap except that it uses reference equality when comparing elements. IdentityHashMap class is not a widely used Map implementation. While this class implements the Map interface, it intentionally violates Map’s general contract, which mandates the use of the equals() method when comparing objects. IdentityHashMap is designed for use only in the rare cases wherein reference-equality semantics are required.
    • WeakHashMap is an implementation of the Map interface that stores only weak references to its keys. Storing only weak references allows a key-value pair to be garbage collected when its key is no longer referenced outside of the WeakHashMap. This class is intended primarily for use with key objects whose equals methods test for object identity using the == operator. Once such a key is discarded it can never be recreated, so it is impossible to do a look-up of that key in a WeakHashMap at some later time and be surprised that its entry has been removed.
  • What are different Collection views provided by Map interface?
    • key set view
    • value set view
    • entry set view
  • How to make a collection read only?
  • Collections.unmodifiableList(list);
  • TreeMap sorted based on the ?
    • Key
  • How to add objects in tree set?
    • While creating the set pass comparator class’s objects as argument.
    • The comparator class’s comparator method should be overridden with needed logic(use properties of the pojo object)
    public static void main(String[] args) { Set set = new TreeSet(new ComparatorSk()); set.add(new Student(2,"sonu")); set.add(new Student(5,"lion")); set.add(new Student(6,"aval")); set.add(new Student(9,"mallan")); set.add(new Student(8,"bilal")); Iterator ir = set.iterator(); while(ir.hasNext()) { Student obj = ir.next(); System.out.println("Id = " +obj.getId()+ " Name = " +obj.getName()); } } public class ComparatorSk implements Comparator { public int compare(Student o1, Student o2) { if(o1.getId() > o2.getId()){ return 1; } else { return -1; } } }
  • Why doesn't Collection extend Cloneable and Serializable?
    • Many Collection implementations (including all of the ones provided by the JDK) will have a public clone method, but it would be mistake to require it of all Collections. For example, what does it mean to clone a Collection that's backed by a terabyte SQL database? Should the method call cause the company to requisition a new disk farm? Similar arguments hold for serializable
    • If the client doesn't know the actual type of a Collection, it's much more flexible and less error prone to have the client decide what type of Collection is desired, create an empty Collection of this type, and use the addAll method to copy the elements of the original collection into the new one.
  • Why Map interface doesn’t extend Collection interface?
    • Although Map interface and it’s implementations are part of Collections Framework, Map are not collections and collections are not Map. Hence it doesn’t make sense for Map to extend Collection or vice versa.
    • If Map extends Collection interface, then where are the elements? Map contains key-value pairs and it provides methods to retrieve list of Keys or values as Collection but it doesn’t fit into the “group of elements” paradigm
  • What is an Iterator?
    • Iterator interface provides methods to iterate over any Collection. 
    •  We can get iterator instance from a Collection using iterator() method.
    • Iterator  always denies other threads to modify the collection object which is being iterated by it.
    •  Iterators allow the caller to remove elements from the underlying collection during the iteration.
  • What is difference between Enumeration and Iterator interface?
    • Enumeration is twice as fast as Iterator and uses very less memory. 
    • Enumeration is very basic and fits to basic needs. But Iterator is much safer as compared to Enumeration because it always denies other threads to modify the collection object which is being iterated by it.
    • Iterators allow the caller to remove elements from the underlying collection that is not possible with Enumeration. 
  • What is different between Iterator and ListIterator?
    • We can use Iterator to traverse Set and List collections whereas ListIterator can be used with Lists only.
    • Iterator can traverse in forward direction only whereas ListIterator can be used to traverse in both the directions.
    • ListIterator inherits from Iterator interface and comes with extra functionalities like adding an element, replacing an element, getting index position for previous and next elements.
  • What do you understand by iterator fail-fast property?
    • Iterator fail-fast property checks for any modification in the structure of the underlying collection everytime we try to get the next element. If there are any modifications found, it throws ConcurrentModificationException
    • All the implementations of Iterator in Collection classes are fail-fast by design except the concurrent collection classes like ConcurrentHashMap and CopyOnWriteArrayList.
    •  Fail-Fast iterators immediately throw ConcurrentModificationException if there is structural modification of the collection. 
    •  Structural modification means adding, removing or updating any element from collection while a thread is iterating over that collection.
    •  Iterator on ArrayList, HashMap classes are some examples of fail-fast Iterator.
    •  How Fail Fast Iterator works ?
      • To know whether the collection is structurally modified or not, fail-fast iterators use an internal flag called modCount(list.modeCount) which is updated each time a collection is modified.
      • Fail-fast iterators checks the modCount flag whenever it gets the next value (i.e. using next() method), and if it finds that the modCount has been modified after this iterator has been created, it throws ConcurrentModificationException.
  • What is difference between fail-fast and fail-safe?
    • Iterator fail-safe property work with the clone of underlying collection, hence it’s not affected by any modification in the collection.
    • By design, all the collection classes in java.util package are fail-fast whereas collection classes in java.util.concurrent are fail-safe.
    • Fail-fast iterators throw ConcurrentModificationException whereas fail-safe iterator never throws ConcurrentModificationException.
  • How to avoid ConcurrentModificationException while iterating a collection?
    • We can use concurrent collection classes to avoid ConcurrentModificationException while iterating over a collection, for example CopyOnWriteArrayList instead of ArrayList.
  • Why there are no concrete(particular) implementations of Iterator interface?
    • Iterator interface declare methods for iterating a collection but it’s implementation is responsibility of the Collection implementation classes.
    • Every collection class that returns an iterator for traversing has it’s own Iterator implementation nested class.
  • What is UnsupportedOperationException?
    • UnsupportedOperationException is the exception used to indicate that the operation is not supported. It’s used extensively in JDK classes, in collections framework java.util.Collections.
    • UnmodifiableCollection throws this exception for all add and remove operations.
  • What is difference between ArrayList and LinkedList?
    • ArrayList is an index based data structure backed by Array, so it provides random access to it’s elements with performance as O(1) but LinkedList stores data as list of nodes where every node is linked to it’s previous and next node. So even though there is a method to get the element using index, internally it traverse from start to reach at the index node and then return the element, so performance is O(n) that is slower than ArrayList.
    • Insertion, addition or removal of an element is faster in LinkedList compared to ArrayList because there is no concept of resizing array or updating index when element is added in middle.
    • LinkedList consumes more memory than ArrayList because every node in LinkedList stores reference of previous and next elements.
  • Which collection classes provide random access of it’s elements?
    • ArrayList, HashMap, TreeMap, Hashtable classes provide random access to it’s elements. 
  • What is EnumSet?
    • java.util.EnumSet is Set implementation to use with enum types. All of the elements in an enum set must come from a single enum type that is specified, explicitly or implicitly, when the set is created.
  • Which collection classes are thread-safe?
    • Vector, Hashtable and Stack are synchronized classes, so they are thread-safe and can be used in multi-threaded environment.
    • Java 1.5 Concurrent API included some collection classes that allows modification of collection while iteration because they work on the clone of the collection, so they are safe to use in multi-threaded environment. 
  • What is BlockingQueue?
    • java.util.concurrent.BlockingQueue is a Queue that supports operations that wait for the queue to become non-empty when retrieving and removing an element, and wait for space to become available in the queue when adding an element.
    • Java provides several BlockingQueue implementations such as ArrayBlockingQueue, LinkedBlockingQueue, PriorityBlockingQueue, SynchronousQueue etc.
    • Also BlockingQueue used for producer-consumer problem.
  •  What is Collections Class?
    • ajava.util.Collections is a utility class consists exclusively of static methods that operate on or return collections. 
    • This class contains methods for collection framework algorithms, such as binary search, sorting, shuffling, reverse etc. 
  • What is Comparable and Comparator interface?
    • Comparable interface has compareTo(T obj) method which is used by sorting methods. We should override this method in such a way that it returns a negative integer, zero, or a positive integer if “this” object is less than, equal to, or greater than the object passed as argument.
    • Comparator interface compare(Object o1, Object o2) method need to be implemented that takes two Object argument, it should be implemented in such a way that it returns negative int if first argument is less than the second one and returns zero if they are equal and positive int if first argument is greater than second one.
    • Comparable helps in preserving default natural sorting, whereas Comparator helps in sorting the elements in some special required sorting pattern.
  • How can we create a synchronized collection from given collection?
  • use Collections.synchronizedCollection(Collection c)
  • What is Big-O notation? Give some examples?
    • The Big-O notation describes the performance of an algorithm in terms of number of elements in a data structure
    • ArrayList get(index i) is a constant-time operation and doesn’t depend on the number of elements in the list. So it’s performance in Big-O notation is O(1).
    • Example 2: A linear search on array or list performance is O(n) because we need to search through entire list of elements to find the element. 
  • Why can’t we write code as List<Number> numbers = new ArrayList<Integer>();?
    • Generics doesn’t support sub-typing because it will cause issues in achieving type safety. That’s why List<T> is not considered as a subtype of List<S> where S is the super-type of T. To understanding why it’s not allowed, let’s see what could have happened if it has been supported.
  • Why can’t we create generic array? or write code as List<Integer>[] array = new ArrayList<Integer>[10];
    • We are not allowed to create generic arrays because array carry type information of it’s elements at runtime. 
    • This information is used at runtime to throw ArrayStoreException if elements type doesn’t match to the defined type. Since generics type information gets erased at runtime by Type Erasure, the array store check would have been passed where it should have failed. Let’s understand this with a simple example code


  • Java collections framework belongs to java.util package       
  •          Collection's works a bit like arrays, except their size can change dynamically, and they have more advanced behaviour than arrays.
  •      There are two "groups" of interfaces: Collection's and  Map's


  1.    Collection
    1. List
      1. The java.util.List interface is a subtype of the java.util.Collection interface
      2. It represents a n ordered list of objects, meaning you can access the elements of a List in a specific order, and by an index too.
      3. You can add an element anywhere in the list, change an element anywhere in the list, or remove an element from any position in the list.
      4. You can also add the same element more than once to a List.
      5. The List Implementations are,
        1. Arraylist
        2. Vector
        3. Linkedlist
    2. Set
      1. It represents set of objects, meaning each element can only exists once in a Set.
      2. Internal datas structure of set is hashmap and unique key feature of hashmap made set accept only unique objects 
      3. The List Implementations are,
        1. HashSet
        2. LinkedHashSet
        3. TreeSet
    3. Queue
      1. A queue is also ordered, but you'll only ever touch elements at one end. All elements get inserted at the "end" and removed from the "beginning" (or head) of the queue. You can find out how many elements are in the queue, but you can't find out what, say, the "third" element is. You'll see it when you get there.
      2. The Queue Implementations are,
        1. Linkedlist
        2. PriorityQueue 
    4. Dequeue
      1. Deque is short for "double ended queue". With an ordinary queue, you add things to one end and take them from the other. With a double ended queue, you can add things to either end, and take them from either end.
      2. The Dequeue Implementations are
        1. Linkedlist
        2. ArrayDeque
    5. Stack
      1.  Stack is liner type data structure, i.e. they are arranging in liner manner. In stack whatever is stored first it comes out last. It works in LIFO manner(Last in first out)
      2. In stack you can’t add element in between. They are like a stack of coins, i.e. if you want to take the last coin, then all the upper coins have to be removed one by one.
  2.    Map
    1. Map Interface Store data as key value pair
      1. Hashmap
      2. Hashtable
      3. Treemap
      4. Linked Hashmap
  • Arraylist
    • ArrayList is implemented as a resizable array. It's elements can be accessed directly by using the get and set methods, since ArrayList is essentially an array.
    • When an element is inserted into an ArrayList, the object will need to expand its internal array if it runs out of room. the ArrayList increases its array size by 50 percent.
  • Vector
    • The chief difference from ArrayList is that its methods are synchronized (ArrayList's are not). That means it is easier to use in multi-threaded environments, but it does incur the synchronization overhead.
    • When an element is inserted into  a Vector, the object will need to expand its internal array if it runs out of room. A Vector defaults to doubling the size of its array
  • Linkedlist
    •  A linked list is a data structure consisting of a group of nodes which together represent a sequence. Each     node is composed of a data and a reference to the next node in the sequence. This structure allows for efficient insertion or removal of elements from any position in the sequence. 
    • In a singly linked list each node has only one link which points to the next node in the list.
  • HashSet
    • It makes no guarantees about the sequence of the elements when you iterate them
  • LinkedHashSet
    • LinkedHashSet differs from HashSet by guaranteeing that the order of the elements during iteration is the same as the order they were inserted into the LinkedHashSet.
  • TreeSet
    • Guarantees the order of the elements when iterated, but the order is the sorting order of the elements.
  • PriorityQueue 
    • Stores its elements internally according to their natural order (if they implement Comparable), or according to a Comparator passed to the PriorityQueue.
  • ArrayDeque
    • ArrayDeque stores its elements internally in an array. If the number of elements exceeds the space in the array, a new array is allocated, and all elements moved over. In other words, the ArrayDeque grows as needed, even if it stores its elements in an array
  • Stack
    • A Stack is a data structure where you add elements to the "top" of the stack, and also remove elements from the top again.
    • This is also referred to as the "Last In First Out (LIFO)" principle.
  • Hashmap
    • HashMap maps a key and a value. It does not guarantee any order of the elements stored internally in the map
  • Hashtable
    • Hashtable is synchronized
    • Hashtable does not allow null keys or values.
  • Treemap
    • TreeMap also maps a key and a value. Furthermore it guarantees the order in which keys or values are iterated - which is the sort order of the keys or values.
  • Linked Hashmap
    • Having order when iterate

Thursday, 7 September 2017


  • Set conatins only unique elements.
  • HashSet achieves uniqueness of its elements by using hashmap
  • Whenever we create an object of hashset inernally it will create an object of hashmap.
  • If we add an element into a set it will store as key for map. But same time we need a value for key. That value can be Object instance.So whenever we add an element to set it will create Hash map entry with key as added element and value as DUMMY Object.
  • There are two possible output we will get we put an entry into a hashmap
    1. null: If the Key is unique and succussfully added to tha map. 2. Old Value of the Key: If the key is duplicate
      SkHashSet.java
package com.sk.custom_hashset; import java.util.HashMap; import java.util.Set; public class SkHashSet { private HashMap MAP = new HashMap(); private static final Object DUMMY = new Object(); public boolean add(E element) { return MAP.put(element, DUMMY) == null; } public int size() { return MAP.size(); } public Set getAll() { return MAP.keySet(); } }
Download Source

Wednesday, 6 September 2017


  • Hashmap stores key value pairs
  • HashMap uses hash to insert and get elements. hash = key.hashCode()%BUCKET_ARRAY_SIZE]
  • Its an array of Entry LinkedList and each LinkedList identifies using hash. LinkedList will be stored in hash index of BUCKET_ARRAY
  • Entries become LinkedList by keeping next entry in current entry.


Steps To create Hashmap
 Entry Class
     It  Make an Entry class to store the HashMap Entries.
Variable: key, value and next
All enties having the same hash[key.hashCode()%BUCKET_ARRAY_SIZE] linked together using next property having the type Entry. next will holds next entry.Always append new entry in last of linked List.
 Put
Finding the bucket(Linked List) using hash[key.hashCode()%BUCKET_ARRAY_SIZE]
if entry is null in bucket then create new Entry and add to array with key.hashCode()%BUCKET_ARRAY_SIZE as key
if bucket already contains entry and key already existing then get entry and override value
if bucket already exists and key not contains then attach new entry at the end of the linkedList[looping till next become null]
 Get
Finding the bucket(LinkedList) using hash[key.hashCode()%BUCKET_ARRAY_SIZE]
Loop entry till entry become and null and return value if key exists while looping
      Entry.java
package com.sk.custom_hashmap; public class Entry { private final K key; private V value; private Entry next; public Entry(K k, V v) { key = k; value = v; } public V getValue() { return value; } public void setValue(V value) { this.value = value; } public Entry getNext() { return next; } public void setNext(Entry next) { this.next = next; } public K getKey() { return key; } }
SkHashMap.java
package com.sk.custom_hashmap; import java.util.HashSet; import java.util.Set; public class SkHashMap { private int BUKET_ARRAY_SIZE = 16;// initial capacity private double LOAD_FACTOR = 0.75; // no.of entries/BUKET_ARRAY_SIZE private Entry[] BUKET_ARRAY = new Entry[BUKET_ARRAY_SIZE]; @SuppressWarnings(value = { "unchecked" }) public void put(K key, V value) { int hash = key.hashCode() % BUKET_ARRAY_SIZE; // finding bucket Entry entry = BUKET_ARRAY[hash]; if (null == entry) { /** * creating a new Entry and add to array if the hash is not present * in bucket array. */ BUKET_ARRAY[hash] = new Entry(key, value); } else { /** * Overrides value if key already exists */ if (entry.getKey().equals(key)) { entry.setValue(value); } else { /** * need to append new Entry in the end.. So traverse across * Entrys till Entry.next ==null */ while (entry.getNext() != null) { entry = entry.getNext(); } entry.setNext(new Entry(key, value)); } } } @SuppressWarnings(value = { "unchecked", "unused" }) public V get(K key) { V value = null; int hash = key.hashCode() % BUKET_ARRAY_SIZE; Entry entry = BUKET_ARRAY[hash]; while (null != entry) { if (entry.getKey().equals(key)) { return entry.getValue(); } entry = entry.getNext(); } return null; } @SuppressWarnings(value = { "unchecked" }) public Set> getEntrySet() { Set> set = new HashSet>(); for (Entry enty : BUKET_ARRAY) { Entry entrry = enty; while (entrry != null) { set.add(entrry); entrry = entrry.getNext(); } } return set; } }
Load Factor
  • Load Factor is a measure, which decides when exactly to increase the hashmap capacity(no.of buckets) to maintain get and put operation complexity of O(1).
  • Default load factor of Hashmap is 0.75 (i.e 75% of current map size).
  • Default capacity of Hashmap is 2^4 = 16 buckets.
  • Let say we have well implemented hashcode() method, which make sure that key-value pair will be well distributed across 16 buckets equally.
  • So, If there are 16 items in hashmap, then good hashcode method will distribute 1 item in each bucket. Searching for any item in this case will take only 1 look up.Now, If there are 32 items in hashmap, then good hashcode method will distribute 2 item in each bucket. Searching for any item in this case will take maximum 2 look up.Now, If there are 128 items in hashmap, then good hashcode method will distribute 8 item in each bucket. Searching for any item in this case will take maximum 8 look up.
  • If the amount of item keeps on increasing and the number of buckets are fixed(16) then at one time, performance of hashmap will start degrading due to large number of items in each bucket.
  • Now, say if there are 5,00,000 items in hashmap, then, good hashcode method will distribute 31,250 items in each bucket. Searching for any item in this case, will require maximum 31,250 look up.
  • If we increase the total number of buckets, when total items in each bucket starts increasing, then we will be able to keep constant number of items in each bucket and maintain the time complexity of O(1) for get and put operation. The decision of "When to increase the number of buckets" is decided by Load Factor.

  • Default, initial capacity of the HashMap is 16 and Load factor is 0.75
  • Load factor = Number of entries in a bucket / capacity(no. of buckets)
  • It is advisable to have a load factor of around 0.75 for keeping the put and get complexity around O(1).
  • Load Factor and Initial Capacity(Number of buckets) can be configured while creation of Hashmap like shown below,
    HashMap m = new HashMap(int initialCapacity, float loadFactor);
  • Rehashing
    • Rehashing is the process of re-calculating the hashcode of already stored entries (Key-Value pairs), to move them to another bigger size hashmap when Load factor threshold is reached.
    • When the number of items in map, crosses the Load factor limit at that time hashmap doubles its capacity and hashcode is re-calculated of already stored elements for even distribution of key-value pairs across new buckets.
    HashMap Collision Occur 

    • There are several class in JDK which are based upon the hash table data structure
      • HashMap,
      • LinkedHashMap,
      • Hashtable,
      • WeakHashMap,
      • IdentityHashMap,
      • ConcurrentHashMap, 
      • TreeMap, and
      • EnumMap.
    • Underlying working of all these Map is pretty much same as discussed in How does HashMap internally works in Java, except some minor differences in their specific behaviors. Since hash table data structure is subject to collision all these implementations are required to handle the collision.
    • A collision will occur when two different keys have the same hashCode, which can happen because two unequal objects in Java can have the same hashCode.
    • HashMap handles collision by using linked list to store map entries ended up in same array location or bucket location
    • From Java 8 onwards, HashMap, ConcurrentHashMap, and LinkedHashMap will use the balanced binary tree in place of linked list to handle frequently hash collisions. The idea is to switch to the balanced tree once the number of items in a hash bucket grows beyond a certain threshold. This will improve the worst case get() method performance from O(n) to O(log n).
    • Legacy class Hashtable which exists in JDK from Java 1 will not use the balanced binary tree to handle frequent hash collision to keep its iteration order intact. This was decided to avoid breaking many legacy Java application which depends upon iteration order of Hashtable.
    • Apart from Hashtable, WeakHashMap and IdentityHashMap will also continue to use the linked list for handling collision even in the case of frequent collisions.
    • TreeMap
      • Treemap class is like HashMap which stores key- value pairs . The major difference is that Treemap  sorts the key in ascending order.
      • It sorts the TreeMap object keys using Red-Black tree algorithm.
      • We should read the pseudo code of Red Black algorithm in order to understand the internal implementation 
        • As the name of the algorithm suggests ,color of every node in the tree is either red or black.
        • Root node must be Black in color.
        • Red node can not have a red color neighbor node.
        • All paths from root node to the null should consist the same number of black nodes 
        • Rotations maintains the inorder ordering of the keys(x,y,z).
        • A rotation can be maintained in O(1) time.

    • Why  java's  treemap does not allow an initial size ?
      • HashMap reallocates its internals as the new one gets inserted while TreeMap does not reallocate nodes on adding new ones. Thus , the size of the TreeMap  dynamically increases if needed , without shuffling the internals. So it is meaningless to set the initial size of the TreeMap .
    • ConcurrentHashMap 
      • public ConcurrentHashMap (int initialCapacity, float loadFactor, int concurrencyLevel)
      • So the above line  creates a new, empty map with the specified initial capacity, load factor and concurrency level.
      • initialCapacity - the initial capacity. The implementation performs internal sizing to accommodate this many elements.
      • concurrencyLevel - the estimated number of concurrently updating threads. The implementation performs internal sizing to try to accommodate this many threads
      • In the ConcurrentHashMap Api , you will find the following constants.
        • static final int DEFAULT_INITIAL_CAPACITY = 16;
        • static final int DEFAULT_CONCURRENCY_LEVEL = 16;
        •  Instead of a map wide lock, ConcurrentHashMap maintains  a list of 16 locks by default ( number of locks equal to the initial capacity , which is by default  16) each of which is used to lock on a single bucket of the Map.

    Download Source

    Monday, 28 August 2017

    1. Please go through this tutorial to understand the basic concept
    2. List returned by Arrays.asList(): it is documented not to support any removing or adding elements. 
    3. If we update a list from a method X by calling another void method Y, list modification will be affected in the list object in the method X.
    4. Because the the same object memory is used when passing the reference. So java is Pass by value. 
    public class MemoryTest { public static void main(String[] args) { MemoryTest mt = new MemoryTest(); mt.scopeTest(); } private void scopeTest() { int numberInt = 2; Integer numberInteger = 10; List numberList = new ArrayList(); numberList.add(10); numberList.add(20); Student student = new Student(); student.setId(1); student.setName("Sonu"); MemoryTest mt = new MemoryTest(); System.out.println("numberInt before = " + numberInt); mt.modifyInt(numberInt); System.out.println("numberInt after = " + numberInt); System.out.println("numberInteger before = " + numberInteger); mt.modifyInteger(numberInteger); System.out.println("numberInteger after = " + numberInteger); System.out.println("numberList before = " + numberList); mt.modifyList(numberList); System.out.println("numberList after = " + numberList); System.out.println("student before = " + student); mt.modifyStudent(student); System.out.println("student after = " + student); } private void modifyInt(int i) { i = 3; } private void modifyInteger(Integer i) { i = 200; } private void modifyList(List list) { list.add(100); } private void modifyStudent(Student student) { student.setId(2); student.setName("Sreenu"); } }

    Output

    numberInt before = 2 numberInt after = 2 numberInteger before = 10 numberInteger after = 10 numberList before = [10, 20] numberList after = [10, 20, 100] student before = 1, Sonu student after = 2, Sreenu

    Search This Blog

    Contact us

    Name

    Email *

    Message *