Google News
logo
Java Collections Interview Questions
In Java, a collection is a framework that provides an architecture for storing and manipulating a collection of objects. In JDK 1.2, a new framework called "Collection Framework" was created, which contains all of the collection classes and interfaces. 
Collections in Java are capable of doing any data operations such as searching, sorting, insertion, manipulation, and deletion.
A single unit of objects in Java is referred to as a collection. The two basic “root” interfaces of Java collection classes are the Collection interface (java.util.Collection) and the Map interface(java.util.Map). Many interfaces (Set, List, Queue, Deque) and classes are available in the Java Collection framework (ArrayList, Vector, LinkedList, PriorityQueue, HashSet, LinkedHashSet, TreeSet).
Collection : In the java.util.package, there is an interface called a collection. It's used to represent a collection of separate objects as a single entity. It's equivalent to the container in the C++ programming language. The collection framework's root interface is referred to as the collection. It has a number of classes and interfaces for representing a collection of individual objects as a single unit. The key sub-interfaces of the collection interface are List, Set, and Queue. Although the map interface is part of the Java collection framework, it does not inherit the interface's collection. The Collection interface's most significant functions are add(), remove(), clear(), size(), and contains().
 
Collections : The java.util.package has a utility class called Collections. It defines various utility methods for working with collections, such as sorting and searching. All of the methods are static. These techniques give developers much-needed convenience, allowing them to interact with Collection Framework more successfully. It provides methods like sort() to sort the collection elements in the normal sorting order, and min() and max() to get the minimum and maximum value in the collection elements, respectively.
Consistent API : The API has a core set of interfaces like Collection, Set, List, or Map, and all the classes (ArrayList, LinkedList, Vector, and so on) that implement these interfaces have some common set of methods.
 
Cuts programming effort : Instead of worrying about the Collection's design, a programmer may concentrate on how best to use it in his program. As a result, the fundamental principle of Object-oriented programming (i.e. abstraction) has been applied successfully.
 
Improves program speed and quality by offering high-performance implementations of useful data structures and algorithms, as the programmer does not have to worry about the optimum implementation of a certain data structure in this scenario. They can simply use the best implementation to improve the performance of their program significantly.
The collection framework has several interfaces, each of which is used to store a different sort of data. The interfaces included in the framework are listed below.
 
* Iterable Interface : This is the collection framework's primary interface. The iterable interface is extended by the collection interface. As a result, all interfaces and classes implement this interface by default. This interface's main purpose is to provide an iterator for the collections. As a result, this interface only has one abstract method, the iterator. 
 
* Collection Interface : The collection framework's classes implement this interface, which extends the iterable interface. This interface covers all of the basic methods that every collection has, such as adding data to the collection, removing data from the collection, clearing data, and so on. All of these methods are incorporated in this interface because they are used by all classes, regardless of their implementation style. Furthermore, including these methods in this interface guarantees that the method names are consistent across all collections. In summary, we may conclude that this interface lays the groundwork for the implementation of collection classes.
 
* List Interface : The collection interface has a child interface called the list interface. This interface is devoted to list data, in which we can store all of the objects in an ordered collection. This also allows for the presence of redundant data. Various classes, such as ArrayList, Vector, Stack, and others, implement this list interface. We can create a list object with any of these classes because they all implement the list.
 
* Queue Interface : A queue interface, as the name implies, follows the FIFO (First In First Out) order of a real-world queue line. This interface is for storing all elements in which the order of the elements is important. When we try to shop at a store, for example, the bills are issued on a first-come, first-served basis. As a result, the individual whose request is first in line receives the bill first. PriorityQueue, Deque, ArrayDeque, and other classes are available. Because all of these subclasses implement the queue, we can use any of them to create a queue object.
 
* Deque Interface : It differs slightly from the queue data structure.  Deque, also known as a double-ended queue, is a data structure in which elements can be added and removed from both ends. The queue interface is extended by this interface. ArrayDeque is the class that implements this interface. Because this class implements the deque, we can use it to create a deque object.
 
* Set Interface : A set is an unordered group of objects in which duplicate values cannot be kept. This collection is utilised when we want to avoid duplication of things and only keep the ones that are unique. Various classes, such as HashSet, TreeSet, LinkedHashSet, and others, implement this set interface. We can create a set object with any of these classes because they all implement the set.
 
* Sorted Set Interface : This interface resembles the set interface in appearance. The only difference is that this interface provides additional methods for maintaining element ordering. The sorted set interface is an extension of the set interface that is used to manage sorted data. TreeSet is the class that implements this interface. We can create a SortedSet object using this class because it implements the SortedSet interface.
The List and Set both extend the collection interface. However, there are some differences between the both which are listed below.
 
* The List can contain duplicate elements whereas Set includes unique items.
* The List is an ordered collection which maintains the insertion order whereas Set is an unordered collection which does not preserve the insertion order.
* The List interface contains a single legacy class which is Vector class whereas Set interface does not have any legacy class.
* The List interface can allow n number of null values whereas Set interface only allows a single null value.
* HashSet maintains no order whereas TreeSet maintains ascending order.
* HashSet impended by hash table whereas TreeSet implemented by a Tree structure.
* HashSet performs faster than TreeSet.
* HashSet is backed by HashMap whereas TreeSet is backed by TreeMap.
* Set contains values only whereas Map contains key and values both.
* Set contains unique values whereas Map can contain unique Keys with duplicate values.
* Set holds a single number of null value whereas Map can include a single null key with n number of null values.
* HashSet contains only values whereas HashMap includes the entry (key, value). HashSet can be iterated, but HashMap needs to convert into Set to be iterated.
* HashSet implements Set interface whereas HashMap implements the Map interface
* HashSet cannot have any duplicate value whereas HashMap can contain duplicate values with unique keys.
* HashSet contains the only single number of null value whereas HashMap can hold a single null key with n number of null values.
* HashMap maintains no order, but TreeMap maintains ascending order.
* HashMap is implemented by hash table whereas TreeMap is implemented by a Tree structure.
* HashMap can be sorted by Key or value whereas TreeMap can be sorted by Key.
* HashMap may contain a null key with multiple null values whereas TreeMap cannot hold a null key but can have multiple null values.
BlockingQueue is an interface which extends the Queue interface. It provides concurrency in the operations like retrieval, insertion, deletion. While retrieval of any element, it waits for the queue to be non-empty. While storing the elements, it waits for the available space. BlockingQueue cannot contain null elements, and implementation of BlockingQueue is thread-safe.
 
Syntax :
public interface BlockingQueue<E> extends Queue <E>
The Collection interface in Java specifies a group of objects called elements. The maintainability and ordering of elements is completely dependent on the concrete implementations provided by each of the Collection. Thus, there is no use of extending the Cloneable and Serializable interfaces.
Below are the main advantages of using the generic collection in Java :
 
* Eliminates the need for typecasting
* Provides stronger type checks at the time of compilation
* Enables the implementation of generic algorithms which makes the code customizable, type-safe and easier to read
Iterator in Java is an interface of the Collection framework present in java.util package. It is a Cursor in Java which is used to iterate a collection of objects. Below are a few other major functionalities provided by the Iterator interface:

* Supports READ and REMOVE Operations.
* Iterator method names are easy to implement
* Traverse a collection object elements one by one
* Known as Universal Java Cursor as it is applicable for all the classes of the Collection framework
The initial implementation of the equals method helps in checking whether two objects are the same or not. But in case you want to compare the objects based on the property you will have to override this method.
Sorting in Java Collections is implemented via Comparable and Comparator interfaces. When Collections.sort()  method is used the elements get sorted based on the natural order that is specified in the compareTo() method. On the other hand when Collections.sort(Comparator) method is used it sorts the objects based on compare() method of the Comparator interface.
The List interface in Java is an ordered collection of elements. It maintains the insertion order and allows duplicate values to be stored within. This interface contains various methods which enables smooth manipulation of elements based on the element index. The main classes implementing the List interface of the Collection framework are ArrayList, LinkedList, Stack, and Vector.
The equals method is used to check the similarity between two objects. In case if the programmer wants to check an object based on the property, then it needs to be overridden.
Equals() verifies whether the number object is equal to the object, which is passed as an argument or not.
 
The syntax of the equals() method is :
public boolean equals(Object o)
This method takes two parameters 1) any object, 2) return value. It returns true if the passed argument is not null and is an object of a similar type having the same numeric value.
 
Example :
import java.lang.Integer;
public class Test { 
   public static void main(String args[]) {
      Integer p = 5;
      Integer q = 20;
      Integer r =5;
      Short s = 5;
      System.out.println(p.equals(q));  
      System.out.println(p.equals(r)); 
      System.out.println(p.equals(s));
   }
}
The benefits of using the generic collection are :
 
* If the programmers are using generic class, they don’t require typecasting.
* It is type-safe and can be checked at the time of compilation.
* It provides the stability of the code by detecting bug at the compilation time.
Programmers can convert an Array to ArrayList using asList() method of Arrays class. It is a static method of Arrays class that accept the List object. The syntax of asList() method is :
Arrays.asList(item)
Java programmers can convert ArrayList to the List object using syntax :
List_object.toArray(new String[List_object.size()])
This is a beginner’s level programming question that an interviewer asks to check your grasp of Collection utility.classes. Collection and Arrays are the two utility classes of the Collection Framework that interviewers are often interested in.
 
Collections offer certain static functions for performing specific tasks on collection types. While Array has utility functions that it performs on array types.
//String array  
String[] num_words = {"one", "two", "three", "four", "five"};
//Use java.util.Arrays class to convert to list 
List wordList = Arrays.asList(num_words);
The Emptyset() method removes the null elements and returns the empty unchangeable set. This immutable set is serializable. The method declaration of the Emptyset() is - public static final <T> Set<T> emptySet().
Understanding how HashMap works, it is easy to know that they depend mainly on equals and hashCode methods of key objects. So, a good key must provide the same hashCode over and over again irrespective of the times it is fetched.
 
In the same way, when compared with the equals method, the same keys must return true and different keys must return false. That’s why the best candidate for HashMap keys is said to be immutable classes.
Both poll() and remove() method is used to remove head object of the Queue.
 
The main difference lies when the Queue is empty(). If Queue is empty then poll() method will return null . While in similar case , remove() method will throw NoSuchElementException . peek() method retrieves but does not remove the head of the Queue. If queue is empty then peek() method also returns null.
Java.util.IdentityHashMap implements Map interface and it does not make use of equals() and hashcode() methods to compare objects insteadIdentityHashMap uses equality operator "==" to compare the key and value objects.
 
The use of the equality operator makes IdentityHashMap perform faster compared to the HashMap and it suits the need where reference equality check is required rather than the logical semantics.
 
IdentityHashMap is not synchronized.
 
Although this class implements the Map interface, it violates the general contract that mandates the use of equals method when comparing key/value objects.
 
This Api is introduced as part of Java 1.4.
Iterator.remove is the only safe way to modify a collection during iteration; the behavior is unspecified if the underlying collection is modified in any other way while the iteration is in progress.
Collection is used for storing data in different data structures while Stream API is used for computation of data on a large set of Objects.
 
Collection API we can store a finite number of elements in a data structure. With Stream API, we can handle streams of data that can contain infinite number of elements.
 
Eager vs. Lazy : Collection API constructs objects in an eager manner. Stream API creates objects in a lazy manner.
 
Multiple consumption : Most of the Collection APIs support iteration and consumption of elements multiple times. With Stream API we can consume or iterate elements only once.
If you change the value in the properties file, you don't need to recompile the java class. So, it makes the application easy to manage. It is used to store information which is to be changed frequently. Consider the following example.
import java.util.*;  
import java.io.*;  
public class Test {  
public static void main(String[] args)throws Exception{  
    FileReader reader=new FileReader("db.properties");  
      
    Properties p=new Properties();  
    p.load(reader);  
      
    System.out.println(p.getProperty("user"));  
    System.out.println(p.getProperty("password"));  
}  
} ​
 Output :
system
oracle

 

Two different keys with the same hash value are known as hash-collision. Two separate entries will be kept in a single hash bucket to avoid the collision. There are two ways to avoid hash-collision.
 
* Separate Chaining
* Open Addressing
The default size of load factor is 0.75. The default capacity is computed as initial capacity * load factor. For example, 16 * 0.75 = 12. So, 12 is the default capacity of Map.
There are two ways to remove duplicates from the ArrayList.
 
Using HashSet : By using HashSet we can remove the duplicate element from the ArrayList, but it will not then preserve the insertion order.
Using LinkedHashSet : We can also maintain the insertion order by using LinkedHashSet instead of HashSet.

The Process to remove duplicate elements from ArrayList using the LinkedHashSet:
 
* Copy all the elements of ArrayList to LinkedHashSet.
* Now copy all the elements of LinkedHashset to ArrayList.
* Empty the ArrayList using clear() method, which will remove all the elements from the list.
Java 5, collections using new approaches to synchronization are available in Java. These are called concurrent collections. Examples of new approaches are :

* Locks
* Copy on Write
* Compare and Swap

These new approaches to concurrency provide better performance in specific context’s.
Compare and Swap is one of the new approaches (Java 5) introduced in java to handle synchronization. In traditional approach, a method which modifies a member variable used by multiple threads is completely synchronized – to prevent other threads accessing stale value.
 
In compare and swap approach, instead of synchronizing entire method, the value of the member variable before calculation is cached. After the calculation, the cached value is compared with the current value of member variable. If the value is not modified, the calculated result is stored into the member variable. If another thread has modified the value, then the calculation can be performed again. Or skipped – as the need might be.
 
ConcurrentLinkedQueue uses this approach.
Atomic Access Java Tutorial states “In programming, an atomic action is one that effectively happens all at once. An atomic action cannot stop in the middle: it either happens completely, or it doesn't happen at all. No side effects of an atomic action are visible until the action is complete”.
 
Let’s assume we are writing a multi threaded program. Let’s create an int variable i. Even a small operation, like i++ (increment), is not thread safe. i++ operation involves three steps.
 
* Read the value which is currently stored in i
* Add one to it (atomic operation).
* Store it in i

In a multi-threaded environment, there can be unexpected results. For example, if thread1 is reading the value (step 1) and immediately after thread2 stores the value (step 3).
 
To prevent these, Java provides atomic operations. Atomic operations are performed as a single unit without interference from other threads ensuring data consistency.
 
A good example is AtomicInteger. To increment a value of AtomicInteger, we use the incrementAndGet() method. Java ensures this operation is Atomic.
A good way to sort Java collection objects is using Comparable and Comparator interfaces. A developer can use Collections.sort(), the elements are sorted based on the order mention in compareTo().
 
When a developer uses Collections, sort (Comparator), it sorts the objects depend on compare() of the Comparator interface.
The methods to make collection thread safe are :
 
* Collections.synchronizedList(list);
* Collections.synchronizedMap(map);
* Collections.synchronizedSet(set);
UnsupportedOperationException is an exception whch is thrown on methods that are not supported by actual collection type.
 
For example, Developer is making a read-only list using “Collections.unmodifiableList(list)” and calling call(), add() or remove() method. It should clearly throw UnsupportedOperationException.
The developer cannot directly iterate map, but, this interface has two methods that gives view set of map. These methods are :
 
Set<Map.Entry<K, V>>entrySet() : It is a method that returns a set having the entries mention in the map. These entries are generally objected, which has type Map. Entry.
Set<K>keySet() : This Java method returns a set that having the map key.
There are three types of queues in Java :
 
Priority queue : It is a special type of Queue wherein elements are sorted as per their natural ordering or custom comparator.
Circular Queue : It is a type of Queue in which user operations are performed based on the FIFO method. The last element is connected to the first position in order to make a circle.
Double-ended Queue : A double-ended queue is an abstract data type that generalizes a queue. The elements in this queue can be added or removed from either head or tail.
The Big-O notation depicts the performance of an algorithm as the number of elements in ArrayList. A developer can use Big-O notation to choose the collection implementation. It is based on performance, time, and memory.
 
For example, ArrayList get(index i) is a method to perform a constant-time operation. It does not depend on the total number of elements available in the list. Therefore, the performance in Big-O notation is O(1).