100 Java Collection Interview Questions and Answers (Part 3)

57.How remove() method is get() method. First we locate the correct bucket in HashMap for an entry. Then within that bucket we remove the element e. It is similar to removing a node from a single-linked list.
implemented in a HashMap?
Remove() method in HashMap uses logic similar to the one used in If e is the first element in the bucket we set the corresponding element of Hash to e.next. Else we set the next field of the element just before e to e.next.

58. What is BlockingQueue in Java Collections?
BlockingQueue was introduced in Java 1.5. It extends Queue interface in Java.
BlockingQueue supports operations that wait for the queue to become non-empty when retrieving an element. Also it supports the operations that wait for space to become available in the queue while storing an element.
Some of the features of BlockingQueue are:

  • It does not accept null elements.
  • Its main use is in producer-consumer problems.
  • BlockingQueue implementation is thread-safe.
  • It can be used in inter-thread communications.
  • It does not support any kind of “close” or “shutdown” operation to indicate that no more items will be added.

59. How is TreeMap class implemented in Java?
Internally, a TreeMap class in Java uses Red-Black tree. It is a NavigableMap. The map sorts the keys in natural order or it can use a Comparator supplied at the creation time.
The implementation of TreeMap is not synchronized in Java.

60. What is the difference between Fail-fast and Fail-safe iterator in Java?
Differences between Fail-fast and Fail-safe iterators are as follows:
Fail-fast iterator throws ConcurrentModificationException. But Fail-safe iterator does not throw this exception. Fail-fast iterator does not clone the original collection. Fail-safe iterator creates a copy of the original collection of objects.
A Fail-fast iterator tries to immediately throw Exception when it encounters failure. A Fail-safe Iterator works on a copy of collection instead of original collection.

61. How does ConcurrentHashMap work in Java?
ConcurrentHashMap extends AbstractMap in Java. It was introduced in Java 1.5. It provides concurrency in a collection based on a HashMap.
All methods are thread-safe in ConcurrentHashMap.
Internally there is a Hashtable backing a ConcurrentHashMap. This Hashtable supports the concurrent methods for retrieval of data as well as updates on ConcurrentHashMap.
It has same functional specification as a Hashtable.
It also supports a set of sequential and bulk operations. These operations accept parallelismThreshold argument.

62. What is the importance of hashCode() and equals() methods?
In a HashMap collection it is very important for a key object to implement hashCode() method and equals() method. If hashCode() method returns same hashcode for all key objects then the hash collision will be high in HashMap. Also with same hashcode, we will get same equals method that will make our HashMap inefficient.
The problem arises when HashMap treats both outputs same instead of different. It will overwrite the most recent key-value pair with the previous key-value pair.
So it is important to implement hashCode() and equals() methods correctly for an efficient HashMap collection.

63. What is the contract of hashCode() and equals() methods in Java?
Contract of hashCode() and equals() methods is as follows in Java:
If object1.equals(object2), then object1.hashCode() == object2.hashCode() should always be true. It means if two objects are equal then their hashCode should be same.
If object1.hashCode() == object2.hashCode() is true, it does not guarantee that object1.equals(object2). It means if two objects have same hashCode, then can still have different values so that may not be equal objects.

64. What is an EnumSet in Java?
Set: EnumSet is a specialized implementation of Set.

  • 1. Use: It is mainly used with enum types.
  • 2. Single enum type: All the elements in an EnumSet must come from a single enum type when the set is created.
  • 3. Bit vector: Internally, EnumSet is represented as bit vector.
  • 4. Iterator: The iterator of EnumSet traverses the elements in their natural order. (It is the order in which the enum constants are declared).
  • 5. Null: In an EnumSet, null elements are not permitted. If we try to insert a null element it throws NullPointerException.
  • 6. Thread-safe: EnumSet is not a synchronized collection. For use in multi-threading scenarios, EnumSet should be synchronized.
  • 7. Bit flags: EnumSet is a very good alternative to int based “bit flags” implementation.

65. What are the main Concurrent Collection classes in Java?
Java 1.5 has provided new package java.util.concurrent. This package contains thread-safe collection classed. These collection classes can be modified while iterating. The iterator of these classes is fail-safe.
Main Concurrent Collection classes in Java 8 are:

  • ArrayBlockingQueue
  • CopyOnWriteArrayList
  • CopyOnWriteArraySet
  • ConcurrentHashMap
  • ConcurrentLinkedDeque
  • ConcurrentLinkedQueue
  • LinkedBlockingQueue
  • LinkedBlockingDeque
  • PriorityBlockingQueue

66.How will you convert a Collection to SynchronizedCollection in Java?
Java provides an easy method in java.utils.Collections class to create a ThreadSafe collection from a regular collection.
We can use the method synchronizedCollection() for this purpose. For any class of type T we can use following method: static Collection synchronizedCollection(Collection c)

67.How IdentityHashMap is different from a regular Map in Java?
IndentityHashMap in Java implements Map interface. But it is not a general purpose implementation. It violates the general contract of Map interface by a different implementation of equals() method.
In an IdentityHashMap, two keys k1 and k2 are equal if and only if (k1==k2). (In a normal Map implementation (like HashMap) two keys k1 and k2 are considered equal if and only if (k1==null ?
k2==null : k1.equals(k2)).)
It implements the Map interface with a hash table, using referenceequality in place of object-equality when comparing keys (and values).

68.What is the main use of IdentityHashMap?
Main uses of IdentityHashMap are:

  • 1. Topology Preservation: The typical use of IdentityHashMap class is topology-preserving object
    graph transformations, such as serialization or deepcopying. In such a scenario, a program must maintain a “node table” to keep track of all the object references that have already been processed.
  • 2. The node table should not considered distinct objects as equal even if they happen to be equal.
  • 3. Proxy objects: Another use of this class is to maintain proxy objects. A debugging program has to maintain a proxy object for each object in the program being debugged.

70.How can we improve the performance of IdentityHashMap?
IdentityHashMap class has one tuning parameter for performance improvement: expectedMaxSize.
This parameter is the maximum number of key-value mappings that the map is expected to hold.
We can use this parameter is used to determine the number of buckets initially in the hash table. The precise relationship between the expected maximum size and the number of buckets is unspecified.
If the number of key-value mappings exceeds the expected maximum size, the number of buckets is increased.
Increasing the number of buckets is also known as rehashing.
Rehashing may be fairly expensive. So it is better to create identity hash maps with a sufficiently large expected maximum size.
But iteration over a Map collection requires time proportional to the number of buckets in the hash table. So iteration may take extra time due to large number of buckets.
Therefore the value of expectedMaxSize should be set in consideration with both of these aspects.

71. Is IdentityHashMap threadsafe?
The implementation of IdentityHashMap is not thread-safe, since its methods are not synchronized.
The iterators returned by the iterator method of IdentityHashMap are fail-fast. But the fail-fast behavior of an iterator cannot be guaranteed. Since the Iterator is fail-fast, it throws ConcurrentModificationException.

72.What is a WeakHashMap in Java?
WeakHashMap is a class similar to IdentityHashMap.
Internally, it is represented by a Hashtable.
It is not a synchronized class. We can make a WeakHashMap thread safe by using Collections.synchronizedMap() method.
An entry in WeakHashMap is automatically removed when it is no longer in ordinary use.
The presence of a mapping for a given key does not prevent the key from being discarded by the garbage collector.
WeakHashMap also permits null keys and null values.

73.How can you make a Collection class read Only in Java?
In Java, there are useful methods to make a Collection class read Only. We can make the Collection read Only by using one of the following methods:

  • Collections.unmodifiableMap(Map m)
  • Collections.unmodifiableList(List l)
  • Collections.unmodifiableSet(Set s)
  • Collections.unmodifiableCollection(Collection c)

74.When is UnsupportedOperationException thrown in Java?
In a Java collection UnsupportedOperationException is thrown when the requested operation is not supported by the collection.
It is an unchecked exception that is thrown on optional operations.
If there is an optional add() or remove() methods in a read only collection, then this exception can be thrown.

75. Let say there is a Customer class. We add objects of Customer class to an ArrayList. How can we sort the Customer objects in ArrayList by using customer firstName attribute of Customer class?
There are two ways to handle this scenario. We can use these options:
Comparable: Implement the Comparable interface for Customer class and compare customer objects by firstName attribute.
Comparator: Implement Comparator for comparing two Customer objects on the basis of firstName attribute. Then use this comparator object in sort method of Collections class.

76.What is the difference between Synchronized Collection and Concurrent Collection?
In Java 1.5 many Concurrent collection classes were added in SDK.
These are ConcurrentHashMap, CopyOnWriteArrayList, BlockingQueue etc.
Java also provides utility methods to get a synchronized copy of collection like ArrayList, HashMap etc. by using Collections.synchronizedList(), Collections.synchronizedMap() methods.
The main difference is in performance. Concurrent collection classes have better performance than synchronized collection classes because they lock only a portion of the class to achieve concurrency and thread-safety.

77. What is the scenario to use ConcurrentHashMap in Java?
ConcurrentHashMap is more suited for scenarios where we have multiple reader threads and one writer thread. In this case map is locked only during the write operation.
If we have an equal number of reader and writer threads then ConcurrentHashMap performance is similar to a Hashtable or a synchronized HashMap.

78.How will you create an empty Map in Java?
There are two ways to create an empty Map in Java.

  • 1. Immutable: If we want an immutable empty Map, we can use following code:
  • 2. Any map: For all other scenarios, we can use following code by using new method:

79. What is the difference between remove() method of Collection and remove() method of Iterator?
In Collection interface remove(Object o) method is used to remove objects from a Collection.
List interface also provides remove(int index) method to remove an object at a specific index.
These methods are used to remove an entry from Collection, while no thread is iterating over it.
When we are iterating over a Collection, then we have to remove() method of Iterator. This method removes current element from Iterator’s point of view. If we use remove(0 method of Collection or List, then we will get ConcurrentModificationException.
Therefore, it is recommended to use remove() method of Iterator during the traversal of a Collection by an Iterator.

80. Between an Array and ArrayList, which one is the preferred collection for storing objects?
An ArrayList is backed up by array internally. There are many usability advantages of using an ArrayList over an array in Java.
Array has a fixed length at the time of creation. Once it is created we cannot change its length.
ArrayList is dynamic in size. Once it reaches a threshold, it automatically allocates a new array and copies contents of old array to new array.
Also ArrayList provides support of Generics. But Array does not support Generics.
E.g. If we store an Integer object in a String array at Runtime it will throw ArrayStoreException. Whereas, if we use ArrayList then as compile time we will get the error. This helps in preventing errors from happening at runtime.
If we know the size in advance and do not need re-sizing the collection then Array should be used in place of an ArrayList.

81. Is it possible to replace Hashtable with ConcurrentHashMap in Java?
Yes, a ConcurrentHashMap can be replaced with Hashtable in Java.
But it requires careful observation, since locking behavior of Hashtable is different than that of ConcurrentHashmap.
A Hashtable locks whole Map instead of a portion of Map. Compound operations like if(Hashtable.get(key) == null) put(key,value) work in Hashtable but not in ConcurrentHashMap.
In a ConcurrentHashMap we use putIfAbsent() method for such a scenario.

82. How CopyOnWriteArrayList class is different from ArrayList and Vector classes?
CopyOnWriteArrayList was introduced in Java 1.5. It implements List interface.
It provides better concurrent access methods than a Synchronized List.
In CopyOnWriteList, concurrency is achieved by copying ArrayList over each write and replace with original instead of locking.
CopyOnWriteArrayList also does not throw any ConcurrentModification Exception during Iteration.
It is a thread-safe list.
It is different from a Vector in terms of Concurrency.
CopyOnWriteArrayList provides better Concurrency by reducing contention among readers and writers.

83. Why ListIterator has add() method but Iterator does not have?
ListIterator can iterate in the both directions of a Collection. It maintains two pointer for previous and next element. In ListIterator we can use add() method to add an element into the list immediately before the element returned by next() method.
So a subsequent call to next() method will not be affected. And the call to previous() method will return the newly added element.
In Iterator we can only traverse in one direction. So there is no purpose of add() method there.

84. Why do we sometime get ConcurrentModificationException during iteration?
When we remove an object by using remove() method of a Collection or List while an Iterator thread is traversing it, we get ConcurrentModificationException. If an Iterator detects any structural change in Collection it can throw ConcurrentModificationException.

85. How will you convert a Map to a List in Java?
In Java, a Map has three collection sets:

  • key set
  • value set
  • key-value set

Each of these Sets can be converted to List by using a constructor.
Sample code is as follows:

  • List keyList = new ArrayList(map.keySet());
  • List valueList = new ArrayList(map.values());
  • List entryList = new ArrayList(map.entrySet());

86. How can we create a Map with reverse view and lookup in Java?
In a Map we can lookup for a value by using a distinct key. In a Map with reverse view and lookup, even the values are distinct. So there is one to one mapping between keys and values and vice version. If we enable this constraint on a Map then we can look up a key by its value. Such data structure is called bi-directional map.
There is no built data structure similar to reverse lookup Map in JDK.
But Apache Common Collections and Guava libraries provide implementation of bidirectional map. It is called BidiMap and BiMap. Both of these data structure enforce the constraint of one to one mapping between keys and values.

87. How will you create a shallow copy of a Map?
In Java, most implementations of Map interface provide a constructor to create copy of another map. But the copy method is not synchronized.
Therefore, when a thread is copying the map, another thread can modify it.
To prevent such a scenario, we should use Collections.synchronizedMap() method to first create a thread-safe
map.
Another way of to create a shallow copy is by using clone() method.
But it is not considered as a recommended approach.

88.Why we cannot create a generic array in Java?
Java does not allow creation of array with generics as elements.
In Java an array has to know the type information of its elements at runtime.
This information is used at runtime to throw ArrayStoreException if data type of an element to be inserted does not match the type of Array.
In case of Generics, the type information of a collection is erased at runtime by Type Erasure. Due to this array cannot use generics as elements.

89. What is a PriorityQueue in Java?
A PriorityQueue is data structure based on Queue. Unlike Queue, the elements on PriorityQueue are not returned in FIFO order.
A PriorityQueue maintains the natural order of its elements or it uses a Comparator provided at initialization.
It is an unbounded queue based on a priority heap.
PriorityQueue does not allow null values. We cannot add any object that does not provide natural ordering to PriorityQueue.
PriorityQueue in Java is not thread-safe.
It gives O(log n) time for enqueing and dequeing operations.

90. What are the important points to remember while using Java Collections Framework?
Some of the important points to remember while using Java
Collections Framework are:

  • 1. Interfaces: For Collections, we should write code with generic interfaces instead of concrete implementation. Due to this we maintain the flexibility of changing the implementation at a later point of time.
  • 2. Generics: We should use Generics for type-safety and to avoid ClassCastException at runtime.
  • 3. Collections: It is recommended to use Collections utility class for algorithms and various other common methods for Collections.
  • 4. Right Type: We have to choose the right type of Java collection based on our need. If size is fixed, we can use Array over ArrayList. If we do not want duplicate elements we use Set. If we need the ability to iterate the elements of a Map in the order of insertion then we use a TreeMap.
  • 5. Initial Size: In some collection classes we can specify the initial size/capacity. Therefore we should have an estimate of number of elements in a Collection before deciding the right collection type. We can use it to avoid rehashing or resizing.
  • 6. Map: We should use immutable classes provided by Java as key elements in a Map.

91. How can we pass a Collection as an argument to a method and ensure that method will not be able to modify it?
To ensure that a method is not able to modify a Collection passed as an argument, we have to make the Collection read only.
We can make a read only collection by using Collections.unmodifiableCollection(Collection c) method.
This will make sure that any operation to change the collection will throw  UnsupportedOperationException.

92. Can you explain how HashMap works in Java?
In Java, a HashMap works on the concept of hashing.
A HashMap in Java stores both key and value objects, in a bucket. It is stored as an Entry object that implements Map.Entry interface.
The key object used in a HashMap has to provide implementation for hashCode() and equals() methods.
When put() method is used to store a key-value pair, the HashMap implementation calls hashCode() method on Key object to calculate a hash that is used to find a bucket where Entry object will be stored.
When get() method is used to retrieve a value stored against a key object, we first calculate a hash of Key object. Then we use this hash to find the bucket in which that particular key is stored.
Once Key object’s location is found, it may happen that more than one Key is stored in same location. So now we use equals() method to find the exact Key object. Once the exact Key object is found we use it to get Value object.

93. Can you explain how HashSet is implemented in Java?
Internally, a HashSet uses a HashMap to store the elements and to maintain the uniqueness of elements.
When we create a HashSet object, a corresponding HashMap object is also created.
When we insert an element in HashSet, it inserts it into corresponding HashMap.

94. What is a NavigableMap in Java?
As the name suggests, NavigableMap provides the capability to navigate the keys of a Map in Java. A NavigableMap extends SortedMap interface.
Some of the interesting methods of a NavigableMap are descendingKeySet(), descendingMap(), headMap() and tailMap().

95. What is the difference between descendingKeySet() and descendingMap() methods of NavigableMap?
The descendingKeySet() method of NavigableMap returns a NavigableSet in which the elements are stored in reversed order as compared to the original key set.
The returned view is internally represented by the original KeySet of NavigableMap. Therefore any changes to the descending set also get reflected in the original set.
But it is not recommended to remove elements directly from the key set. We should use the Map.remove() method.
The descendingMap() method of NavigableMap returns a NavigableMap which is an inverse view of the original Map. The order of the elements in this view are in reverse order of the elements in original map. Any changes to this view are also reflected in the original map.

96. What is the advantage of NavigableMap over Map?
The main advantage of NavigableMap over Map is the Navigation capability.
It provides the capabilities of a Map, SortedMap and navigation in one collection.
It even returns the closest matches for given search targets.
Methods like lowerEntry, floorEntry, ceilingEntry, and higherEntry return Map.Entry objects associated with keys respectively less than, less than or equal, greater than or equal, and greater than a given key.
Methods like lowerKey, floorKey, ceilingKey, and higherKey return only the associated keys. All of these  methods are designed for locating, not traversing entries.

97. What is the difference between headMap(), tailMap() and subMap() methods of NavigableMap?
The headMap() method returns a view of the original NavigableMap that contains the elements that are less than a given element.

The tailMap() method works similar to headMap() method, but it returns all elements that are higher than the given input element. The subMap() method accepts two parameters demarcating the boundaries of the view map to return.
All the three methods return a subset of the original map in a view form.

98. How will you sort objects by Natural order in a Java List?
We can use Collections.sort method to sort the elements of a List in natural order. To use this method, we have to make sure that element objects implement compareTo() method.
We can also use a Comparator to define the natural ordering for elements of a List. Then we can use this Custom Comparator in sort method of Collections class.

99. How can we get a Stream from a List in Java?
From Java 8 onwards it is a very easy to get a Stream from a List.
We can just use stream() method to get a stream from a list of elements.

100. Can we get a Map from a Stream in Java?
Yes, we can create a Map from the elements of a Stream. We can use map() method to get a Map.
E.g.

In this example we are creating a map with each item object mapped to its LowerCase equivalent.
This is also used in Map-Reduce implementation on a Stream.
101. What are the popular implementations of Deque in Java?
The two most popular implementation of Deque interface in Java are:

  • 1. ArrayDeque: It is a resizable array implementation of Deque. The capacity of ArrayDeque can increase based on the need of the program. It is not thread safe implementation. Also the iterator on ArrayDeque is failfast.
  • 2. LinkedList: This is another popular implementation of Deque interface in Java. It is also not synchronized, so it is not thread-safe. It mainly provides functionality of a doubly linked list.

Leave a Comment

Please share it if you found this useful
Hide Buttons