Showing posts with label collection interview questions with answers in java. Show all posts
Showing posts with label collection interview questions with answers in java. Show all posts

Tuesday, 13 April 2021

Java Collection Framework Best Practices

       In this article we can discuss the best practices of java collection and sample examples for each usages.

1) Choose the right collection

        This is the most important step before using any collection. Depending upon functionality or problem solve to decide the right collection to use in the code implementation. There are multiple criteria to choose right collection - 

1) collection allows duplicates or not 

2) accepts null or not 

3) search based on index

4) Supports concurrency.

and also the developer should know the performance impact on each collection usages.


2) Use interface type when declaring any collection.

When you declare or create any collection, prefer to use interface type instead of specific collection class.

Example:-

List<String> listOfItems = new ArrayList<>();

instead of,

ArrayList<String> listOfItems = new ArrayList<>();

Using interface type is more flexible and convenient because we can change concreate implementation as needed.

For example,  List<String> listOfItems = new LinkedList<>();


3) Method return type should be interface instead of collection class.

       Best practice to return type of method should be interface instead of collection class. It is more flexible because if any changes done inside the method should not impact on the caller.

 public List<String> getAllItems() {
      
      List<String> listOfItems = new ArrayList<>();
      
      //in future if we change arrayList to linkedList it doesn't impact on caller
      // get all items - fetch items from database

      return listOfItems;
 }

4) Use generic type and diamond operator

        Use generic type when declare any collection otherwise chances of throwing ClassCastException at run time.

Example : - 

List listOfItems = new ArrayList<>();

listOfItems.add("item");

listOfItems.add(1);

so avoid using above declaration, apply generics,

List<String> listOfItems = new ArrayList<>();

listOfItems.add("company");

listOfItems.add(12);     //compile time error

 Use diamond operator(<>),

This operator <> is called the diamond operator. Without diamond operator we have to write declaration twice so using this operator no need to write declaration twice as follows,

List<String> listOfItems = new ArrayList<String>();

With <> operator,

List<String> listOfItems = new ArrayList<>();


5) Prefer to use Collection isEmpty() or CollectionUtils.isEmpty()  methods instead of size() method

Checking the emptiness of collection, avoid using size method like,

if  (listOfItems.size > 0)  {
   //write logic if list is not empty
}

Prefer to use collection or collection util methods,

if  (!listOfItems.isEmpty())  {
    //write logic if list is not empty
}

or use collection util(apache) method,

if (CollectionUtils.isNotEmpty(listOfItems)) {
      //write logic if list is not empty
}


6) Specify initial capacity of a collection if possible

        When we process a batch of records then prefer to specify the collection initial capacity as a batch size so it avoids every time to resize the collection capacity when it exceeds the default capacity.

List<String> listOfItems = new ArrayList<>(500);

This creates an array list of 500 elements initially.

7)  Return an empty array or collection instead of a null value for methods that return an array or collection

       If the method is collection valued then return empty collection instead of returning null because the client side no need to handle null check it's kind of extra
code to write in the client side. 

//Avoid this
public List<String> getAllPreSaleItems(String itemType) {
		
	List<String> preSaleItems = null;
	if (itemType.equalsIgnoreCase("preSale")) {
		//preSaleItems = fetch all presale items from database
	}
	return preSaleItems;
}

Best practice to return empty list as, 

//best practice to return empty list
private List<String> getAllPreSaleItems(String itemType) {
		
	List<String> preSaleItems = null;
	if (itemType.equalsIgnoreCase("preSale")) {
		//preSaleItems = fetch all presale items from database
	}
	if (preSaleItems == null) {
		return Collections.EMPTY_LIST;
	}
	return preSaleItems;
}

8) Do not use the classic for loop

Classic for loop,

List<String> listOfItems = Arrays.asList("a", "b", "c");
for (int i=0; i<listOfItems.size(); i++) {
   System.out.println(listOfItems(i));
}

Better to use for-each loop,

List<String> listOfItems = Arrays.asList("a", "b", "c");
for (String item : listOfItems) {
   System.out.println(item);
}

The advantage of the for-each loop is that it eliminates the possibility of bugs and makes the code more readable. It traverses each element one by one. 

9) Prefer to use forEach() with Lambda expressions(Java 8 onwards)

       In forEach() method use java 8 lambda expression,  so that the code even more compact, more flexible and more powerful.

Example:-

List<String> skuList = Arrays.asList("MTCCC", "MTAAA", "PT1111");
 
skuList.forEach(sku -> System.out.println(sku));


10) Prefer concurrent collections over synchronized wrappers

          When we develop any multi-threaded applications,  consider using concurrent collections in the java.util.concurrent package instead of using the synchronized 
collections generated by the Collections.synchronizedXXX() methods.
         It’s because the concurrent collections are designed to provide maximum performance in concurrent applications,  by implementing different synchronization mechanisms like copy-on-write, compare-and-swap and special locks. 
 
Example of concurrent package classes are ConcurrentHashMap, CopyOnWriteArrayList, ConcurrentSkipListMap and PriorityBlockingQueue.


Related Posts:-

Sunday, 20 October 2019

Difference between fail-safe and fail-fast iterator in Java

        In the current interview topic, we will discuss the difference between fail safe and fail fast iterators in Java. Basically this question is related to ConcurrentModificationException, means what are the scenario to throw this exception. The above iterator one it will throw exception and another one doesn't throw, this is the main difference. We can discuss few more differences and with examples as follows

Related topicDifference between HashSet and TreeSet in Java

Difference between fail-fast and fail-safe iterator:-
diff. between fail-fast and fail-safe
Difference between fail-fast and fail-safe iterator

Example of fail-fast iterator:-

         As we see the difference between fail-fast and fail-safe in the diagram, the mainly difference is to throw the ConcurrentModificationException. In any type of Collection, internally it will use an array of objects to store the elements. While iterating the collection, we can not modify the existing array. Internally collection will use flag to indicate whether the given collection is modified or not. Based on this flag it will throw the exception if flag is true.

FailFastIteratorExample.java,
package com.example.demo;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class FailFastIteratorExample {

        public static void main(String[] args) {

                List<String> list = new ArrayList<String>();
                list.add("A");
                list.add("B");

                Iterator<String> iterator = list.iterator();

                while (iterator.hasNext()) {
                        iterator.next();
                        list.add("C");
                }
        }

}

Output:-
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at com.example.demo.FailFastIteratorExample.main(FailFastIteratorExample.java:17)


Example Of fail-safe iterator:-

           The fail-safe iterator doesn't throw any exception if the collection is modified while iterating over it. Internally it will copy the original collection object, and iterate over the copied collection object. Due to this internal behavior, if any modification done on collection, it doesn't impact on iterator.

FailSafeIteratorExample.java,
package com.example.demo;

import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

public class FailSafeIteratorExample {

        public static void main(String[] args) {

               List<String> list = new CopyOnWriteArrayList<String>();
               list.add("A");
               list.add("B");

               Iterator<String> iterator = list.iterator();

               while (iterator.hasNext()) {
                       iterator.next();
                       list.add("C");
               }

               list.forEach(str -> System.out.println(str));

       }

}

Output:-
A
B
C
C

Related Posts:-
1) Collection Hierarchy in Java
2) Collection Interview Questions and Answers in Java(List,Map & Set)
3) How to iterate the TreeMap in reverse order in Java
4) How to Remove duplicates from ArrayList in Java
5) Internal Implementation of TreeMap in Java
6) Internal implementation of ArrayList in Java
7) Internal Implementation of LinkedList in Java
8) Difference between HashSet and TreeSet in Java

Wednesday, 9 October 2019

UnsupportedOperationException when adding or removing element to a Collection in java

          In earlier article, we discussed the difference between HashSet and TreeSet and also covered sample example of TreeSet and HashSet.  In the current article, we will see one of important exception in collection i.e UnsupportedOperationException.


What is UnsupportedOperationException in collection?

          The name itself suggests provided operation can not be  supported i.e when you try to perform some operation on collection where it's not allowed and will throw UnsupportedOperationException. The UnsupportedOperationException is thrown at run time so it's RuntimeException i.e Unchecked Exception.

Throwable -> Exception -> RuntimeException -> UnsupportedOperationException


Scenario to throw UnsupportedOperationException:-

1) Update on list of Arrays.asList() 

      As we know that, Converting from Array to List we will use asList() method of Arrays(java.util.Arrays) class.  When you convert array to list using asList method, and try to add an element to a list then will throw UnsupportedOperationException as shown below code.

UnsupportedOpExceptionExample.java,
package com.example.demo;

import java.util.Arrays;
import java.util.List;

public class UnsupportedOpExceptionExample {
     
     public static void main(String[] args) {
          
           String[] arrayStr = { "Mechanical", "Computer Science" };
           List<String> list = Arrays.asList(arrayStr);
           list.add("ECE");
     }
}

Output:-
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(Unknown Source)
at java.util.AbstractList.add(Unknown Source)
at com.example.demo.UnsupportedOpExceptionExample.main(UnsupportedOpExceptionExample.java:12)



Solution:-

Pass Arrays.asList to the List constructor, so that will act as new ArrayList object, then you can modify the list without any exception.

UnsupportedOpExceptionExample.java
package com.example.demo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class UnsupportedOpExceptionExample {

       public static void main(String[] args) {

              String[] arrayStr = { "Mechanical", "Computer Science" };
              List<String> list = new ArrayList<String>(Arrays.asList(arrayStr));
              list.add("ECE");

              list.stream().forEach(str -> System.out.println(str));
       }
}
Output:-
Mechanical
Computer Science
ECE



2) Update on Unmodifiable collection

           You can create any Unmodifiable collection class by using Collections.unmodifiableCollection (Collection obj) method. When you create unmodifiable collection, you can not modify i.e it's read only access. If you try to update on Unmodifiable collection, it will throw RuntimeException i.e UnsupportedOperationException.

        Sample java code to throw UnsupportedOperationException when try to update Unmodifiable collection,

UnsupportedOpExceptionExample.java
package com.example.demo;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

public class UnsupportedOpExceptionExample {

        public static void main(String[] args) {

               List<String> list = new ArrayList<String>();
               list.add("Mechanical");
               list.add("ECE");
               Collection<String> strList = Collections.unmodifiableCollection(list);
               strList.add("CS");

               list.stream().forEach(str -> System.out.println(str));
        }

}

Output:-
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.Collections$UnmodifiableCollection.add(Unknown Source) at com.example.demo.UnsupportedOpExceptionExample.main(UnsupportedOpExceptionExample.java:16)

   If really you are not doing any update on collection then use this method, otherwise don't use.

Thank you for visiting blog....

Sunday, 6 October 2019

Why TreeSet does not allow null value in Java?

           TreeSet implements Set interface and maintains unique elements which means it doesn't allow duplicates. The elements in the TreeSet are sorted and in ascending order. In this post, we will discuss about why TreeSet doesn't allow to add null value.

Example to add null value to TreeSet:--


TreeSetExample.java

package com.example.demo;

import java.util.TreeSet;

public class TreeSetExample {

         public static void main(String[] args) {

                 TreeSet<String> treeSet = new TreeSet<String>();
                  treeSet.add(null);

         }

}

Output:-
Exception in thread "main" java.lang.NullPointerException
at java.util.TreeMap.compare(Unknown Source)
at java.util.TreeMap.put(Unknown Source)
at java.util.TreeSet.add(Unknown Source)
at com.example.demo.TreeSetExample.main(TreeSetExample.java:10)


Why TreeSet doesn't allow to add null value ?

TreeSet internally used Comparable interface to sort the elements in ascending order. In Comparable interface there is method called compareTo() used to compare one value with other to sort the elements. So null doesn't have any value because of this reason compareTo() method can not compare null with other value, giving NullPointerException.

add method declaration :-


public boolean add(E e) throws ClassCastException, NullPointerExeption;


Java 1.6 and earlier versions, TreeSet allow to add first element as null. From 1.7 onwards null is not accepted at all.


Thank you for visiting the blog.

Saturday, 5 October 2019

Difference between HashSet and TreeSet in Java

        In the current post, we will see what are the differences between HashSet and TreeSet in Java. Both TreeSet and HashSet implements Set interface and doesn't contain duplicates.

Difference between HashSet and TreeSet:-

1) HashSet gives better performance compared to TreeSet for the operations like add, remove, contains, size etc. HashSet offers constant time cost while TreeSet offers log(n) time cost for such operations.

2) HashSet is implemented based on HashTable while TreeSet is implemented based on TreeMap. As we know that TreeMap uses a Red-Black algorithm to sort the elements.

3) HashSet does not maintain any order of elements while TreeSet elements are sorted by ascending order by default. Both HashSet and TreeSet doesn't contain duplicate elements.

4) HashSet allows null values but TreeSet doesn’t allow null values. If try to add null value in TreeSet will throw NullPointerException, because internally TreeSet uses compareTo() method to compare keys and compareTo() will throw NullPointerException.

     Use TreeSet if you need the inserted elements in sorted ascending order but performance wise HashSet is better.

HashSet and TreeSet examples:--

HashSetTreeSetExample.java
package com.example.demo;

import java.util.HashSet;
import java.util.TreeSet;

public class HashSetTreeSetExample {

       public static void main(String[] args) {

               HashSet<String> hashSet = new HashSet<String>();
               hashSet.add("Java");
               hashSet.add(".Net");
               hashSet.add("PHP");
               hashSet.add("Embedded C");

               System.out.println("HashSet elements are,");
               hashSet.stream().forEach(System.out::println);

               TreeSet<String> treeSet = new TreeSet<String>();
               treeSet.add("Java");
               treeSet.add(".Net");
               treeSet.add("PHP");
               treeSet.add("Embedded C");

               System.out.println("TreeSet elements are,");
               treeSet.stream().forEach(System.out::println);
       }
}

Output:--
HashSet elements are,
Java
Embedded C
.Net
PHP

TreeSet elements are,
.Net
Embedded C
Java
PHP


Thank you for visiting the blog.

Thursday, 3 October 2019

Collection Hierarchy in Java

           A Collection is a group of objects represented as a single unit and which defines several classes and interfaces. Collection framework is very important topic for java interview questions, you can read usage, difference and advantages of all interfaces and classes .

In the current post, we will discuss collection hierarchy.

      All classes and interfaces related to Collection Framework are in java.util package. Collection interface is at the top of class hierarchy of Collection Framework as shown in below diagram.

Below diagram shows the class hierarchy of collection framework.

Collection Hierarchy in Java
Collection Hierarchy in Java

        The Collection Framework is divided into four interfaces(three interfaces inherits Collection interface, but map interface is not inherits Collection interface, this is a separate interface ).

  •  List 
      ArrayList, Vector and LinkedList classes implement this interface. It contains duplicates.

  • Queue
      It handles the special group of objects in which elements are removed only from the head. LinkedList and PriorityQueue classes implement this interface.

  • Set
      HashSet and LinkedHashSet classes implements Set interface and TreeSet class implements SortedSet interface which in turn, is extends Set interface. It doesn't contain duplicates.

  • Map
       This is the one interface in Collection Framework which is not inherited from Collection interface. It handles the group of objects as Key/Value pairs. It is implemented by HashMap and HashTable classes and extended by SortedMap interface which in turn is implemented by TreeMap.

Friday, 29 December 2017

How to Remove duplicates from ArrayList in Java

     I have shared the code to remove duplicates from ArrayList with primitive and custom objects. You can use set interface class, so it can not add elements to the class.

1) Remove duplicates from ArrayList with String as Generics.

Example:--

package com.test;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

public class RemoveDuplicates {
 
      public static void main(String[] args) {
  
            List<String> list = new ArrayList<String>();
            list.add("Mahesh");
            list.add("Nagesh");
            list.add("Lohit");
            list.add("Mahesh"); 
            System.out.println("List with duplicates:");
            for (String name : list) {
                 System.out.println(name);
            }
  
            /* Convert list to LinkedHashSet, to preserve the insertion 
              order and remove the duplicates */
  
            Set<String> set = new LinkedHashSet<String>(list);
            System.out.println("Set with unique elements:");
            for (String name: set) {
                 System.out.println(name);
            }
      }
}

Output :--
List with duplicates:
Mahesh
Nagesh
Lohit
Mahesh
Set with unique elements:
Mahesh
Nagesh
Lohit


2) Remove duplicates from ArrayList with Custom Object as Employee

Example:--
Employee class is as below, override equals and hashCode methods.

package com.test;

public class Employee {
 
     private int empId;
     private String empName;
 
     public Employee(int empId, String empName) {
          this.empId = empId;
          this.empName = empName;
     }
 
     public int getEmpId() {
          return empId;
     }
     public void setEmpId(int empId) {
          this.empId = empId;
     }
     public String getEmpName() {
          return empName;
     }
     public void setEmpName(String empName) {
          this.empName = empName;
     }
 
     @Override
     public int hashCode() {
          return this.empId;
     }
 
     @Override
     public boolean equals(Object obj) {
          if (obj instanceof Employee) {
               return ((Employee)obj).empId == this.empId;
          }
          return false;
    }
}

Main class ,

package com.test;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

public class RemoveCustomDuplicates {
 
      public static void main(String[] args) {
  
            Employee emp1 = new Employee(1, "Kiran");
            Employee emp2 = new Employee(2, "Mahesh");
            Employee emp3 = new Employee(3, "Lakshmi");
            Employee emp4 = new Employee(1, "Kiran");
  
            List<Employee> list = new ArrayList<Employee>();
  
            list.add(emp1);
            list.add(emp2);
            list.add(emp3);
            list.add(emp4); 
            System.out.println("List with duplicates:");
            for (Employee emp : list) {
                 System.out.println(emp.getEmpName());
            }
  
            /* Convert list to LinkedHashSet, to preserve the insertion 
             order and remove the duplicates */
  
           Set<Employee> set = new LinkedHashSet<Employee>(list);
           System.out.println("Set with unique elements:");
           for (Employee emp: set) {
                System.out.println(emp.getEmpName());
           }
      }

}

Output : --
List with duplicates:
Kiran
Mahesh
Lakshmi
Kiran
Set with unique elements:
Kiran
Mahesh
Lakshmi

Thanks for visiting blog.

Thursday, 7 December 2017

Example to sort keys of TreeMap using Comparator with Custom Object

        In the below code, we are passing custom object as key in TreeMap i.e Employee user defined class. In this case, we need to pass the comparator object in the constructor, while creating the TreeMap object.  In the Comparator, need to override the compare method and to write the sorting logic.

 Example:--

package com.test;

import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;

public class TreeMapSorting { 
 
     public static void main(String[] args) { 
 
           TreeMap<Employee, String> treeMap = new TreeMap<Employee, String>(new MyNameComp()); 
 
           treeMap.put(new Employee(10,  "Anil"), "one");
           treeMap.put(new Employee(10,  "Mahesh"), "two");
           treeMap.put(new Employee(10,  "John"), "three");
           treeMap.put(new Employee(10,  "Nagesh"), "four");
           for (Map.Entry<Employee, String> map : treeMap.entrySet()) {
                 System.out.println("Key : ("+map.getKey()+ "), Value : "+ map.getValue());
           }
     }
}
 
class Employee { 
 
     private Integer id;
     private String name; 
 
     public Employee(Integer id, String name) {
          this.id = id;
          this.name = name;
     }
     public Integer getId() {
          return id;
     }
     public void setId(Integer id) {
          this.id = id;
     }
     public String getName() {
          return name;
     }
     public void setName(String name) {
          this.name = name;
     }
     public String toString() {
          return this.name+":"+id;
     }
}

class MyNameComp implements Comparator<Employee> {

     public int compare(Employee o1, Employee o2) {
            return o1.getName().compareTo(o2.getName());
     }
 
}

Output : -Key : (Anil:10), Value : one
               Key : (John:10), Value : three
              Key : (Mahesh:10), Value : two
              Key : (Nagesh:10), Value : four



Related Post :--
How to iterate the TreeMap in reverse order in Java  
Internal Implementation of TreeMap in Java  
Internal Implementation of LinkedList in Java  
Internal implementation of ArrayList in Java  
How HashMap works internally in Java?