Java Collections
Java Collections
But the Collection interface extends Iterable interface. Due to this some people
consider Iterable interface as the root interface.
3. Collection defines methods that are used for data structures that contain
the objects. Collections defines the methods that are used for operations
like access, find etc. on a Collection.
148. What are the Thread-safe classes in Java
Collections framework?
Stack
Properties
Vector
Hashtable
BlockingQueue
ConcurrentMap
ConcurrentNavigableMap
149. How will you efficiently remove elements while
iterating a Collection?
The right way to remove elements from a collection while iterating is by using
ListIterator.remove() method.
E.g.
An iterator is first created to traverse the list. But at the same time the list is
changed by remove() method.
In Java, it is not allowed for a thread to modify a collection while another thread is
iterating it. ListIterator provides the capability of removing an object during
traversal.
150. How will you convert a List into an array of integers like- int[]?
We can use ArrayUtils in Apache Commons Lang library for this purpose.
The other option would be to use a for loop and explicitly adding integers to a List.
int[]intArray = {10,20,30};
List<Integer> intList = new ArrayList<Integer>(); for (int i:
intArray) {
intList.add(i);
}
152. How will you run a filter on a Collection?
We can use CollectionUtils of Apache for this purpose. We will have to create a
Predicate that will define the condition for our filter. Then we can apply this
Predicate in filter() method.
In this example we filter any names that are less than 5 characters long.
In this case we put a list into a HashSet. Internally hashCode() method is used to
identify duplicate elements.
The trick in this question is to use a collection that does not allow duplicate
elements. So we use a Set for this purpose.
In Java, there are many ways to maintain a Collection with elements in sorted
order.
Some collections like TreeSet store elements in the natural ordering. In case of
natural ordering we have to implement Comparable interface for comparing the
elements.
Another option is to use the utility method Collections.sort() to sort a List. This
sorting gives nlog(n) order of performance. But if we have to use this method
multiple times then it will be costly on performance.
Another option is to use a PriorityQueue that provides an ordered queue. The main
difference between PriorityQueue and Collections.sort() is that PriorityQueue
maintains a queue in Order all the time, but we can only retrieve head element from
queue. We cannot access the elements of PriorityQueue in Random order.
We can use TreeSet to maintain sorted order of elements in collection if there are
no duplicate elements in collection.
156. What are the differences between the two data structures: a Vector
and an ArrayList?
ArrayList is more popular than LinkedList in Java due to its ease of use and
random access to elements feature.
But LinkedList is better in the scenario when we do not need random access to
elements or there are a lot of insertion, deletion of elements.
159. What are the differences between a List and Set collection in Java?
3. Duplicate: In a List we can store duplicate elements. A Set can hold only
unique elements.
160. What are the differences between a HashSet and TreeSet collection
in Java?
1. If we want a Collection that does not store duplicate values, then we use
a Set based collection.
2. If we want to frequently access elements operations based on an index
value then we use a List based collection. E.g. ArrayList
4. For fast search operation based on a key, value pair, we use a HashMap
based collection.
2. Null values: A HashMap allows only one null key and any number of
null values. A Hashtable does not allow null keys and null values.
The equals() method in Object class is used to check whether two objects are same
or not. If we want a custom implementation we can override this method.
For example, a Person class has first name, last name and age. If we want two
Person objects to be equal based on name and age, then we can override equals()
method to compare the first name, last name and age of Person objects.
Object class in Java has hashCode() method. This method returns a hash code
value, which is an integer.
The hashCode() is a native method and its implementation is not pure Java.
Collections.copy() does not reallocate the capacity of destination List if it does not
have enough space to contain all elements of source List. It throws
IndexOutOfBoundsException.
The benefit of Collection.copy() is that it guarantees that the copy will happen in
linear time. It is also good for the scenario when we want to reuse an array instead
of allocating more memory in the constructor of ArrayList.
One limitation of Collections.copy() is that it can accept only List as source and
destination parameters.
171. What are the Java Collection classes that implement List interface?
AbstractList
AbstractSequentialList
ArrayList
AttributeList
CopyOnWriteArrayList
LinkedList
RoleList
RoleUnresolvedList
Stack
Vector
172. What are the Java Collection classes that implement Set
interface?
AbstractSet
ConcurrentSkipListSet
CopyOnWriteArraySet
EnumSet
HashSet
JobStateReasons
LinkedHashSet
TreeSet
Iterator and ListIterator are two interfaces in Java to traverse data structures. The
differences between these two are:
1. ListIterator can be used to traverse only a List. But Iterator can be used
to traverse List, Set, and Queue etc.
Both Iterator and Enumeration are interfaces in Java to access Data Structures. The
main differences between these are:
2. Null values: A Set allows inserting maximum one null value. In a Map
we can have single null key at most and any number of null values.
3. Ordering: A Set does not maintain any order of elements. Some of sub-
classes of a Set can sort the elements in an order like LinkedHashSet. A
Map does not maintain any order of its elements. Some of its sub-classes
like TreeMap store elements of the map in ascending order of keys.
177. What is the use of a Dictionary class?
The Dictionary class in Java is used to store key-value pairs. Any non-null object
can be used for key or value. But we cannot insert a null key or null object in
Dictionary.
A HashMap in Java has default initial capacity 16 and the load factor is 0.75f (i.e.
75% of current map size). The load factor of a HashMap is the level at which its
capacity should be doubled.
For example, in a HashMap of capacity 16 and load factor .75. The capacity will
become 32 when the HashMap is 75% full. Therefore, after storing the 12th key–
value pair (16 * .75 = 12) into HashMap, its capacity becomes 32.
180. What are the major differences between a HashSet and a
HashMap?
As the name suggests, HashSet and HashMap are Hashing based collections.
Similarities between HashSet and HashMap are:
The equals() method in Object class is used to check whether two objects are same
or not. If we want a custom implementation we can override this method.
For example, a Person class has first name, last name and age. If we want two
Person objects to be equal based on name and age, then we can override equals()
method to compare the first name, last name and age of Person objects.
In a Hashing scenario, at times two different objects may have same HashCode but
they may not be equal. Therefore, Java will face issue while storing the two
different objects with same HashCode in a HashMap. This kind of situation is Hash
Collision.
Queue is a FIFO data structure. FIFO stands for First In First Out. It means the
element added first will be removed first from the queue. A real world example of
Queue is a line for buying tickets at a station. The person entering first in the Queue
is served first.
Stack is a LIFO data structure. LIFO stands for Last In First Out.
The element that is added last is removed first from the collection.
In a Stack elements are added or removed from the top of stack.
A real world example of Stack is back button in browser. We can go back one by
one only and it works in the reverse order of adding
webpages to history .
187. What is an Iterator in Java?
In Collections class, Java provides a method reverse(List list) that can be used to
reverse a List.
E.g.
Collections.reverse(myList);
192. How will you convert an array of String objects into a List?
Java provides Arrays class in java.util package. Arrays class has a method asList()
that accepts an Array as input and returns a List as output.
193. What is the difference between peek(), poll() and remove() methods
of Queue interface in java?
In a Java Queue, poll() and remove() methods can be used for removing the head
object of Queue. The main difference arises in the case when Queue is empty().
If Queue is empty then poll() method returns null value. If Queue is empty then
remove() method throws NoSuchElementException.
In a Java Queue, peek() method retrieves the head of Queue but it does not remove
it. If queue is empty then peek() method returns null value.
194. What is the difference between Array and ArrayList in Java?
1. Size: Array in Java is fixed in size. We cannot change the size of array
after creating it. ArrayList is dynamic in size. When we add elements to
an ArrayList, its capacity increases automatically.
Hashtable
Collections.SynchronizedMap
ConcurrentHashMap
HashMap
Hashtable has the worst performance and HashMap has the best performance.
198. Why does Map interface not extend Collection interface in
Java?
A Map is a collection objects. But Map interface is not compatible with Collection
interface in Java.
But Collection interface provides add(Object o) method with only one parameter.
Map collection has to provide methods like valueSet, keySet etc. These methods
are specific to Map collection. Where as methods in Collection interface can be
reused by a List, Set, Queue etc.
There are mainly two ways to iterate the elements of list in Java:
1. Iterator: We can get an Iterator for list and use it to iterate the objects
of the list.
2. For-each loop: We can use for-each loop to traverse all the elements of
a list.
Remove() method in HashMap uses logic similar to the one used in 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.
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.
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.
It is a NavigableMap. The map sorts the keys in natural order or it can use a
Comparator supplied at the creation time.
Fail-fast iterator does not clone the original collection. Fail-safe iterator creates a
copy of the original collection of objects.
It also supports a set of sequential and bulk operations. These operations accept
parallelismThreshold argument.
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.
2. Single enum type: All the elements in an EnumSet must come from a
single enum type when the set is created.
7. Bit flags: EnumSet is a very good alternative to int based “bit flags”
implementation.
209. 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.
ArrayBlockingQueue
CopyOnWriteArrayList
CopyOnWriteArraySet
ConcurrentHashMap
ConcurrentLinkedDeque
ConcurrentLinkedQueue
LinkedBlockingQueue
LinkedBlockingDeque
PriorityBlockingQueue
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 reference-equality in place
of object-equality when comparing keys (and values).
212. What is the main use of IdentityHashMap?
2. The node table should not considered distinct objects as equal even if
they happen to be equal.
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.
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.
The iterators returned by the iterator method of IdentityHashMap are fail-fast. But
the fail-fast behavior of an iterator cannot be guaranteed.
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)
217. When is UnsupportedOperationException thrown in Java?
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.
Java also provides utility methods to get a synchronized copy of collection like
ArrayList, HashMap etc. by using
Collections.synchronizedList(), Collections.synchronizedMap() methods.
myMap = Collections.emptyMap();
2. Any map: For all other scenarios, we can use following code by using
new method:
These methods are used to remove an entry from Collection, while no thread is
iterating over it.
Array has a fixed length at the time of creation. Once it is created we cannot change
its length.
Also ArrayList provides support of Generics. But Array does not support Generics.
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.
It is a thread-safe list.
226. Why ListIterator has add() method but Iterator does not
have?
So a subsequent call to next() method will not be affected. And the call to
previous() method will return the newly added element.
key set
value set
key-value set
229. 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.
Therefore, when a thread is copying the map, another thread can modify it.
In Java an array has to know the type information of its elements at runtime.
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.
This will make sure that any operation to change the collection will throw
UnsupportedOperationException.
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.
236. 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.
As the name suggests, NavigableMap provides the capability to navigate the keys
of a Map in Java. A NavigableMap extends SortedMap interface.
But it is not recommended to remove elements directly from the key set. We should
use the Map.remove() method.
Methods like lowerKey, floorKey, ceilingKey, and higherKey return only the
associated keys. All of these methods are designed for locating, not traversing
entries.
The headMap() method returns a view of the original NavigableMap that contains
the elements that are less than a given element.
//this headmap2 will contain elements "1", "2", and "3" because "inclusive"=true
NavigableMap headmap2 = original.headMap("3", true);
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.
241. 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.
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.
Yes, we can create a Map from the elements of a Stream. We can use map()
method to get a Map.
E.g. items.stream()
.map( item -> item.toLowerCase() )
In this example we are creating a map with each item object mapped to its
LowerCase equivalent.