Java Collections is a topic much brought up on technical interviews for Java developers. This article reviews some important questions that are asked most frequently and may be slippery to get right .
Q1. Describe the Collections Type Hierarchy. What Are the Main Interfaces, and What Are the Differences Between Them?
The Iterable interface represents any collection that can be iterated using the for-each loop. The Collection interface inherits from Iterable and adds generic methods for checking if an element is in a solicitation, adding and removing elements from the collection, determining its size etc .
The List, Set, and Queue interfaces inherit from the Collection interface .
List is an order collection, and its elements can be accessed by their index in the tilt .
Set is an disordered collection with distinct elements, alike to the mathematical notion of a set. Queue is a solicitation with extra methods for adding, removing and examining elements, useful for holding elements anterior to process .
Map interface is besides a share of the collection model, yet it does not extend Collection. This is by design, to stress the difference between collections and mappings which are hard to gather under a coarse abstraction. The Map interface represents a key-value data structure with unique keys and no more than one value for each key .
Q2. Describe Various Implementations of the Map Interface and Their Use Case Differences.
One of the most much use implementations of the Map interface is the HashMap. It is a distinctive hash function data structure that allows accessing elements in changeless fourth dimension, or O ( 1 ), but does not preserve order and is not thread-safe .
To preserve interpolation order of elements, you can use the LinkedHashMap class which extends the HashMap and additionally ties the elements into a linked list, with foreseeable overhead. The TreeMap class stores its elements in a red-black tree structure, which allows accessing elements in logarithmic meter, or O ( log ( newton ) ). It is slower than the HashMap for most cases, but it allows keeping the elements in ordain according to some Comparator .
The ConcurrentHashMap is a thread-safe implementation of a hash function. It provides fully concurrence of retrievals ( as the get operation does not entail locking ) and high expected concurrence of updates .
The Hashtable classify has been in Java since version 1.0. It is not deprecated but is by and large considered disused. It is a thread-safe hashish map, but unlike ConcurrentHashMap, all its methods are simply synchronized, which means that all operations on this map block, even recovery of autonomous values .
Q3. Explain the Difference Between Linkedlist and Arraylist.
ArrayList is an implementation of the List interface that is based on an align. ArrayList internally handles resize of this align when the elements are added or removed. You can access its elements in changeless prison term by their index in the array. however, inserting or removing an element infers shifting all attendant elements which may be slow if the array is huge and the insert or removed element is close to the begin of the number. LinkedList is a doubly-linked number : single elements are put into Node objects that have references to previous and next Node. This implementation may appear more effective than ArrayList if you have lots of insertions or deletions in different parts of the list, particularly if the list is large .
In most cases, however, ArrayList outperforms LinkedList. tied elements shifting in ArrayList, while being an O ( n ) operation, is implemented as a very fast System.arraycopy ( ) cry. It can even appear faster than the LinkedList ‘ second O ( 1 ) interpolation which requires instantiating a Node object and updating multiple references under the hood. LinkedList besides can have a large memory viewgraph ascribable to a creation of multiple little Node objects .
Q4. What Is the Difference Between Hashset and Treeset?
Both HashSet and TreeSet classes implement the Set interface and represent sets of distinct elements. additionally, TreeSet implements the NavigableSet interface. This interface defines methods that take advantage of the order of elements .
HashSet is internally based on a HashMap, and TreeSet is backed by a TreeMap example, which defines their properties : HashSet does not keep elements in any detail ordain. iteration over the elements in a HashSet produces them in a shuffle ordain. TreeSet, on the other pass, produces elements in order according to some predefined Comparator .
Q5. How Is Hashmap Implemented in Java? How Does Its Implementation Use Hashcode and Equals Methods of Objects? What Is the Time Complexity of Putting and Getting an Element from Such Structure?
The HashMap class represents a typical hash map data structure with certain design choices .
The HashMap is backed by a resizable array that has a size of power-of-two. When the element is added to a HashMap, beginning its hashCode is calculated ( an int value ). then a certain number of lower bits of this value are used as an array index. This index directly points to the cell of the array ( called a bucket ) where this key-value pair should be placed. Accessing an element by its index in an array is a very fast O ( 1 ) operation, which is the independent feature of a hashish function structure. A hashCode is not unique, however, and even for different hashCodes, we may receive the lapp array position. This is called a collision. There is more than one way of resolving collisions in the hashish map data structures. In Java ‘s HashMap, each bucket actually refers not to a unmarried aim, but to a red-black corner of all objects that landed in this bucket ( prior to Java 8, this was a associate list ).
so when the HashMap has determined the bucket for a key, it has to traverse this tree to put the key-value pair in its invest. If a couple with such key already exists in the bucket, it is replaced with a new one .
To retrieve the aim by its key, the HashMap again has to calculate the hashCode for the key, find the corresponding bucket, traverse the tree, call equals on keys in the corner and find the matching one .
HashMap has O ( 1 ) complexity, or constant-time complexity, of putting and getting the elements. Of course, lots of collisions could degrade the performance to O ( log ( n ) ) time complexity in the worst case, when all elements land in a single bucket. This is normally solved by providing a dependable hash serve with a undifferentiated distribution .
When the HashMap internal array is filled ( more on that in the following question ), it is automatically resized to be doubly as large. This operation infers rehashing ( rebuilding of inner data structures ), which is costly, so you should plan the size of your HashMap advance .
Q6. What Is the Purpose of the Initial Capacity and Load Factor Parameters of a Hashmap? What Are Their Default Values?
The initialCapacity controversy of the HashMap builder affects the size of the inner data structure of the HashMap, but reasoning about the actual size of a map is a bite slippery. The HashMap ‘ s internal datum social organization is an range with the power-of-two size. So the initialCapacity argument value is increased to the adjacent power-of-two ( for exemplify, if you set it to 10, the actual size of the inner array will be 16 ) .
The load factor of a HashMap is the ratio of the element reckon divided by the bucket count ( i.e. internal array size ). For case, if a 16-bucket HashMap contains 12 elements, its load divisor is 12/16 = 0.75. A senior high school load factor means a lot of collisions, which in turn means that the map should be resized to the adjacent ability of two. So the loadFactor argument is a maximum prize of the load divisor of a map. When the map achieves this load divisor, it resizes its inner array to the next power-of-two value. The initialCapacity is 16 by nonpayment, and the loadFactor is 0.75 by nonpayment, so you could put 12 elements in a HashMap that was instantiated with the nonpayment builder, and it would not resize. The same goes for the HashSet, which is backed by a HashMap example internally .
consequently, it is not trivial to come up with initialCapacity that satisfies your needs. This is why the Guava library has Maps.newHashMapWithExpectedSize ( ) and Sets.newHashSetWithExpectedSize ( ) methods that allow you to build a HashMap or a HashSet that can hold the expect number of elements without resizing .
Q7. Describe Special Collections for Enums. What Are the Benefits of Their Implementation Compared to Regular Collections?
EnumSet and EnumMap are special implementations of Set and Map interfaces correspondingly. You should constantly use these implementations when you ‘re dealing with enums because they are very effective .
An EnumSet is equitable a bit vector with “ ones ” in the positions corresponding to ordinal number values of enums present in the set. To check if an enum measure is in the specify, the implementation plainly has to check if the represent act in the vector is a “ one ”, which is a identical easy process. similarly, an EnumMap is an array accessed with enum ‘s ordinal value as an exponent. In the case of EnumMap, there is no want to calculate hashish codes or resolve collisions .
Q8. What Is the Difference Between Fail-Fast and Fail-Safe Iterators?
Iterators for different collections are either fail-fast or fail-safe, depending on how they react to concurrent modifications. The coincident change is not only a change of collection from another thread but besides modification from the same screw thread but using another iterator or modifying the collection directly .
Fail-fast iterators ( those returned by HashMap, ArrayList, and early non-thread-safe collections ) iterate over the solicitation ‘s internal data structure, and they throw ConcurrentModificationException arsenic soon as they detect a coincident change .
Fail-safe iterators ( returned by thread-safe collections such as ConcurrentHashMap, CopyOnWriteArrayList ) create a replicate of the structure they iterate upon. They guarantee guard from coincident modifications. Their drawbacks include excessive memory consumption and iteration over possibly outdated data in case the collection was modified .
Q9. How Can You Use Comparable and Comparator Interfaces to Sort Collections?
The comparable interface is an interface for objects that can be compared according to some ordain. Its individual method is compareTo, which operates on two values : the object itself and the argumentation object of the lapp type. For example, Integer, Long, and other numeric types follow through this interface. String besides implements this interface, and its compareTo method acting compares strings in lexicographic order .
The comparable interface allows to sort lists of corresponding objects with the Collections.sort ( ) method acting and uphold the iteration regulate in collections that implement SortedSet and SortedMap. If your objects can be sorted using some logic, they should implement the comparable interface .
The comparable interface normally is implemented using natural ordering of the elements. For example, all Integer numbers are ordered from lesser to greater values. But sometimes you may want to implement another kind of rate, for exemplify, to sort the numbers in descending order. The Comparator interface can help here .
The class of the objects you want to sort does not need to implement this interface. You plainly create an follow through class and define the comparison method acting which receives two objects and decides how to order them. You may then use the case of this class to override the lifelike regulate of the Collections.sort ( ) method or SortedSet and SortedMap instances .
As the Comparator interface is a functional interface, you may replace it with a lambda formula, as in the pursuit example. It shows ordering a tilt using a natural order ( Integer ‘ s Comparable interface ) and using a custom-made iterator ( Comparator
list1 = Arrays.asList(5, 2, 3, 4, 1); Collections.sort(list1); assertEquals(new Integer(1), list1.get(0)); List list1 = Arrays.asList(5, 2, 3, 4, 1); Collections.sort(list1, (a, b) -> b - a); assertEquals(new Integer(5), list1.get(0));
future »Java Type System Interview Questions
Read more: Top 3 interview with questions in 2022
Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:
>> CHECK OUT THE COURSE
Generic pedestrian standard