0% found this document useful (0 votes)
78 views78 pages

Java Collections Explained

The document discusses the importance and basic interfaces of the Java Collections Framework. It provides concise summaries of 10 key points from the document: 1) Containers in the Collections Framework provide advantages over arrays like being dynamic, sorted, unique, and an effective way to persist data. 2) The basic interfaces are Collection, Set, List, and Map. 3) The Collection interface does not extend Cloneable or Serializable because specific implementations should decide how they are cloned or serialized. 4) Map does not extend Collection because maps contain key-value pairs instead of elements.

Uploaded by

fake
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
78 views78 pages

Java Collections Explained

The document discusses the importance and basic interfaces of the Java Collections Framework. It provides concise summaries of 10 key points from the document: 1) Containers in the Collections Framework provide advantages over arrays like being dynamic, sorted, unique, and an effective way to persist data. 2) The basic interfaces are Collection, Set, List, and Map. 3) The Collection interface does not extend Cloneable or Serializable because specific implementations should decide how they are cloned or serialized. 4) Map does not extend Collection because maps contain key-value pairs instead of elements.

Uploaded by

fake
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOC, PDF, TXT or read online on Scribd
You are on page 1/ 78

1)What is the importance of Collection API?

Ans:- What if u want to have a collection of


data items ?
e.g. Strings, numbers, characters
,objects etc.
one way is to create array. They are
efficient.
But if we have following needs :
a)Dynamic array
b)Sorted data
c)uniqueness
d)key-value storage
e)effective way of persisting

Arrays can not fulfill above needs. We


have to use containers for that.

Containers
Give us advantages such as
 Dynamic
 Sorted Order
 Uniqueness
 Thread-safe
 Performance
 Key-value storage , convenient for
retrieval by passing a key.
 Provide effective way of storing and
maintaining data inside the file
system.

Iterators
Allow us to traverse through the
container.
Algorithms
Allow us to perform tasks such as
min,max, sort etc. on the data structure.
2)What are the basic interfaces of Java
Collections Framework?
Ans:- Collection is the root of the collection
hierarchy. A collection represents a group of
objects known as its elements. The Java platform
doesn’t provide any direct implementations of this
interface.
Set is a collection that cannot contain duplicate
elements. This interface models the mathematical
set abstraction and is used to represent sets, such
as the deck of cards.
List is an ordered collection and can contain
duplicate elements. You can access any element
from it’s index. List is more like array with dynamic
length.
A Map is an object that maps keys to values. A
map cannot contain duplicate keys: Each key can
map to at most one value.
Some other interfaces are Queue, Dequeue,
Iterator, SortedSet, SortedMap and
ListIterator.

3)Why Collection doesn’t extend Cloneable


and Serializable interfaces?
Ans:- Collection interface specifies group of
Objects known as elements. How the
elements are maintained is left up to the
concrete implementations of Collection. For
example, some Collection implementations
like List allow duplicate elements whereas
other implementations like Set don’t.
A lot of the Collection implementations have a
public clone method. However, it doesn’t really
make sense to include it in all implementations
of Collection. This is because Collection is an
abstract representation. What matters is the
implementation.
The semantics and the implications of either
cloning or serializing come into play when
dealing with the actual implementation; so
concrete implementation should decide how it
should be cloned or serialized, or even if it can
be cloned or serialized.
So mandating cloning and serialization in all
implementations is actually less flexible and
more restrictive. The specific implementation
should make the decision as to whether it can
be cloned or serialized.
4)Why Map interface doesn’t extend
Collection interface?
Ans:- Although Map interface and it’s
implementations are part of Collections
Framework, Map are not collections and
collections are not Map. Hence it doesn’t make
sense for Map to extend Collection or vice
versa.
If Map extends Collection interface, then
where are the elements? Map contains key-
value pairs and it provides methods to retrieve
list of Keys or values as Collection but it
doesn’t fit into the “group of elements” pattern.
5)What is an Iterator?
Ans:- Iterator interface provides methods to
iterate over any Collection. We can get iterator
instance from a Collection using iterator()
method. Iterator takes the place of
Enumeration in the Java Collections
Framework. Iterators allow the caller to
remove elements from the underlying
collection during the iteration. Java Collection
iterator provides a generic way for traversal
through the elements of a collection and
implements Iterator Design Pattern.
6)What is difference between Enumeration
and Iterator interface?
ans:- both are used to traverse through the
collection implementations. The difference is
Iterators allow the caller to remove elements
from the underlying collection that is not
possible with Enumeration. Iterator method
names have been improved to make its
functionality clear.
7)What is the difference between Iterator and
ListIterator?
Ans:-
 We can use Iterator to traverse Set and List
collections whereas ListIterator can be used
with Lists only.
 Iterator can traverse in forward direction only
whereas ListIterator can be used to traverse in
both the directions.
 ListIterator inherits from Iterator interface and
comes with extra functionalities like adding an
element, replacing an element, getting index
position for previous and next elements.
8)What are different ways to iterate over a
list?
Ans:- We can iterate over a list in two different
ways – using iterator and using for-each loop.
List<String> strList = new
ArrayList<String>();
//using for-each loop
for(String obj : strList)
{
    System.out.println(obj);
}

//using iterator
Iterator<String> it = strList.iterator();
while(it.hasNext())
{
    String obj = it.next();
    System.out.println(obj);
}
Using iterator is more thread-safe because it
makes sure that if underlying list elements are
modified, it will throw
ConcurrentModificationException.

9)What do you understand by iterator fail-fast


property?
Ans:-Iterator fail-fast property checks for any
modification in the structure of the underlying
collection everytime we try to get the next
element. If there are any modifications found,
it throws ConcurrentModificationException.
All the implementations of Iterator in Collection
classes are fail-fast by design except the
concurrent collection classes like
ConcurrentHashMap and
CopyOnWriteArrayList.
10) What is difference between iterator
being fail-fast and fail-safe?
Ans:- Iterator fail-safe property work with the
clone of underlying collection, hence it’s not
affected by any modification in the collection.
By design, all the collection classes in java.util
package are fail-fast whereas collection
classes in java.util.concurrent are fail-safe.
Fail-fast iterators throw
ConcurrentModificationException whereas fail-
safe iterator never throws
ConcurrentModificationException.
11) Why there are no concrete
implementations of Iterator interface?
Ans:- Iterator interface declare methods for
iterating a collection but its implementation is
responsibility of the Collection implementation
classes. Every collection class that returns an
iterator for traversing has its own Iterator
implementation nested class.
This allows collection classes to choose
whether iterator is fail-fast or fail-safe. For
example ArrayList iterator is fail-fast whereas
CopyOnWriteArrayList iterator is fail-safe.
Following are some of the contents of
“ArrayList” class:
public Iterator<E> iterator() {
return new Itr();
}

/**
* An optimized version of AbstractList.Itr
*/
private class Itr implements Iterator<E> {
int cursor; // index of next element to
return
int lastRet = -1; // index of last element
returned; -1 if no such
int expectedModCount = modCount;

public boolean hasNext() {


return cursor != size;
}

@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData =
ArrayList.this.elementData;
if (i >= elementData.length)
throw new
ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}

public void remove() {


if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();

try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new
ConcurrentModificationException();
}
}

@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<?
super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData =
ArrayList.this.elementData;
if (i >= elementData.length) {
throw new
ConcurrentModificationException();
}
while (i != size && modCount ==
expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce
heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}

final void checkForComodification() {


if (modCount != expectedModCount)
throw new
ConcurrentModificationException();
}
}

Following are some of the contents of


“CopyOnWriteArrayList”:

public Iterator<E> iterator()


{
return new COWIterator<E>(getArray(), 0);
}

static final class COWIterator<E> implements


ListIterator<E> {
/** Snapshot of the array */
private final Object[] snapshot;
/** Index of element to be returned by
subsequent call to next. */
private int cursor;

private COWIterator(Object[] elements, int


initialCursor) {
cursor = initialCursor;
snapshot = elements;
}

public boolean hasNext() {


return cursor < snapshot.length;
}

public boolean hasPrevious() {


return cursor > 0;
}

@SuppressWarnings("unchecked")
public E next() {
if (! hasNext())
throw new NoSuchElementException();
return (E) snapshot[cursor++];
}

@SuppressWarnings("unchecked")
public E previous() {
if (! hasPrevious())
throw new NoSuchElementException();
return (E) snapshot[--cursor];
}

public int nextIndex() {


return cursor;
}

public int previousIndex() {


return cursor-1;
}

/**
* Not supported. Always throws
UnsupportedOperationException.
* @throws UnsupportedOperationException
always; {@code remove}
* is not supported by this iterator.
*/
public void remove() {
throw new
UnsupportedOperationException();
}

/**
* Not supported. Always throws
UnsupportedOperationException.
* @throws UnsupportedOperationException
always; {@code set}
* is not supported by this iterator.
*/
public void set(E e) {
throw new
UnsupportedOperationException();
}

/**
* Not supported. Always throws
UnsupportedOperationException.
* @throws UnsupportedOperationException
always; {@code add}
* is not supported by this iterator.
*/
public void add(E e) {
throw new
UnsupportedOperationException();
}

@Override
public void forEachRemaining(Consumer<?
super E> action) {
Objects.requireNonNull(action);
Object[] elements = snapshot;
final int size = elements.length;
for (int i = cursor; i < size; i++) {
@SuppressWarnings("unchecked") E e
= (E) elements[i];
action.accept(e);
}
cursor = size;
}
}

/**
* Returns a view of the portion of this list
between
* {@code fromIndex}, inclusive, and {@code
toIndex}, exclusive.
* The returned list is backed by this list, so
changes in the
* returned list are reflected in this list.
*
* <p>The semantics of the list returned by this
method become
* undefined if the backing list (i.e., this list) is
modified in
* any way other than via the returned list.
*
* @param fromIndex low endpoint (inclusive) of
the subList
* @param toIndex high endpoint (exclusive) of
the subList
* @return a view of the specified range within
this list
* @throws IndexOutOfBoundsException
{@inheritDoc}
*/
public List<E> subList(int fromIndex, int
toIndex) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
if (fromIndex < 0 || toIndex > len ||
fromIndex > toIndex)
throw new
IndexOutOfBoundsException();
return new COWSubList<E>(this,
fromIndex, toIndex);
} finally {
lock.unlock();
}
}

12) How HashMap works in Java?


Ans:- HashMap stores key-value pair in Map.Entry
static nested class implementation. HashMap
works on hashing algorithm and uses hashCode()
and equals() method in put and get methods.
When we call put method by passing key-value
pair, “put” method invokes “hash()” method on Key
hashCode() and finds out the index to store the
key-value pair. Now when u put another entry,
there are two scenarios of hash collision:
a)Hashcode of the given entry is same as
existing entry/entries. – in this case == is
called on key, if it matches, it overwrites
the value. If == doesn’t match, then
“equals()” is invoked ,if it returns true then
overwrites the value. If not linked list is
formed.
b) Hashcode of the given entry is different
from the existing keys in the map, but
index returned from the “hash()” is same
as that of existing entries. – in this case
also linked list is formed.
a and b prove that hash collision can
happen in two cases ie. When hashcode is
same as existing entries or when
hashcode is different but index is same as
that of existing entries.
When we call get method by passing Key, again it
uses “hash()” function which uses the hashCode()
of given key to find the index in the array and then
uses ==. If == returns true, it returns the value , if it
returns false,then equals() method is invoked , if it
returns true value is returned otherwise next node
inside the linkedlist is traversed to find the correct
Entry and return it’s value. Below image will
explain these details clearly.

13) What are the changes java8 brought to


the Map implementations?
Ans:- Prior to Java 8, HashMap and all other hash table based Map
implementation classes in Java handle collision by chaining, i.e. they use linked
list to store map entries which ended in the same bucket due to a collision. If a
key end up in same bucket location where an entry is already stored then this
entry is just added at the head of the linked list there. In the worst case this
degrades the performance of the get() method of HashMap to O(n) from O(1). In
order to address this issue in the case of frequent HashMap collisions, Java8 has
started using a balanced tree instead of linked list for storing collided entries. This
also means that in the worst case you will get a performance boost
from O(n) to O(log n).

The threshold of switching to the balanced tree is defined as TREEIFY_THRESHOLD


constant in java.util.HashMap JDK 8 code.  Currently, it's value is 8, which
means if there are more than 8 elements in the same bucket than HashMap will use
a tree instead of linked list to hold them in the same bucket. 
So far (until JDK 8) only ConcurrentHashMap, LinkedHashMap and HashMap will use the
balanced tree in case of a frequent collision. Also, this feature will not available to all
hash table based classes in Java e.g. Hashtable will not have this feature because of its
legacy nature and given that this feature can change the traditional legacy iteration order
of Hashtable. Similarly, WeakHashMap will also not include this feature.

14) What is the importance of hashCode()


and equals() methods?
ans:- HashMap uses Key object hashCode() and
equals() method to determine the index to put the
key-value pair. These methods are also used
when we try to get value from HashMap. If these
methods are not implemented correctly, two
different Key’s might produce same hashCode()
and equals() output and in that case rather than
storing it at different location, HashMap will
consider them same and overwrite them.
Similarly all the collection classes that doesn’t
store duplicate data use hashCode() and equals()
to find duplicates, so it’s very important to
implement them correctly. The implementation of
equals() and hashCode() should follow these
rules.
 If o1.equals(o2), then o1.hashCode() ==
o2.hashCode()should always be true.
 If o1.hashCode() == o2.hashCode is true, it
doesn’t mean that o1.equals(o2) will be true.
15) Can we use any class as Map key?
Ans:- We can use any class as Map Key, however
following points should be considered before using
them.
 If the class overrides equals() method, it
should also override hashCode() method.
 If a class field is not used in equals(), you
should not use it in hashCode() method.
 Best practice for user defined key class is to
make it immutable in order to ensure that
hashCode() and equals() will not change in
future that will solve any issue with mutability.
For example, let’s say I have a class MyKey
that I am using for HashMap key.

//MyKey name argument passed is used for


equals() and hashCode()
MyKey key = new MyKey("Pankaj"); //assume
hashCode=1234
myHashMap.put(key, "Value");
 
// Below code will change the key hashCode()
and equals()
// but it's location is not changed.
key.setName("Amit"); //assume new
hashCode=7890
 
//below will return null, because HashMap will
try to look for key
//in the same index as it was stored but since
key is mutated,
//there will be no match and it will return null.
myHashMap.get(key);
 This is the reason why String and Integer are
mostly used as HashMap keys.
16) How to convert an array of String to
List?
Ans:-
String array
String[] words =
{“one”,”two”,”three”};
//Use Arrays utility class
List wordList = Arrays.asList(words);
//Now you can iterate over the list
Note that this function is not specific to String
class, it will return List of element of any type, of
which the array is. e.g.
//String array
Integer[] nums = {1,2,3,4};
//Use Arrays utility class
List numsList =
Arrays.asList(nums);
17) How HashSet store elements?
Ans:- You must know that HashMap store key-
value pairs, with one condition i.e. keys will be
unique. HashSet uses Map’s this feature to ensure
uniqueness of elements. In HashSet class, a map
declaration is as below:
private transient HashMap<E,Object> map;
 
//This is added as value for each key
private static final Object PRESENT = new
Object();
So when you store a element in HashSet, it
stores the element as key in map and
“PRESENT” object as value. (See declaration
above).
public boolean add(E e)
{
return map.put(e,
PRESENT)==null;
}

18) Why we use Map interface? What are


main classes implementing Map interface?
Ans:- Map interface is a special type of collection
which is used to store key-value pairs. It does
not extend Collection interface for this reason. This
interface provides methods to add, remove, search
or iterate over various views of Map.
Main classes implementing Map interface are:
HashMap, Hashtable, EnumMap,
IdentityHashMap, LinkedHashMap and
Properties.
19) Difference between HashMap or
TreeMap?
Ans:- HashMap is used to store key-value pairs
and allows to perform many operations on such
collection of pairs.
TreeMap is special form of HashMap. It maintains
the ordering of keys which is missing in
HashMap class. This ordering is by default
“natural ordering”. The default ordering can be
override by providing an instance of Comparator
class, whose compare method will be used to
maintain ordering of keys.
All keys inserted into the map must implement
the Comparable interface (this is necessary to
decide the ordering.
20) Difference between Set and List.
 Ans:- Set is unordered collection where List is
ordered collection based on zero based index.
 List allow duplicate elements but Set does not
allow duplicates.
 List does not prevent inserting null elements
(as many you like), but Set will allow only one
null element.
21) Difference between HashMap and
HashTable
Ans:- There are several differences between
HashMap and Hashtable in Java:
 Hashtable is synchronized, whereas HashMap
is not.
 Hashtable does not allow null keys or values.
HashMap allows one null key and any number
of null values.
 The third significant difference between
HashMap vs Hashtable is that Iterator in the
HashMap is a fail-fast iterator while the
enumerator for the Hashtable is not.
22) Difference between Vector and
ArrayList.
 Ans:- All the methods of Vector is
synchronized. But, the methods of ArrayList is
not synchronized.
 Vector is a Legacy class added in first release
of JDK. ArrayList was part of JDK 1.2, when
collection framework was introduced in java.
 By default, Vector doubles the size of its array
when it is re-sized internally. But, ArrayList
increases by half of its size when it is re-sized.
23) Difference between Iterator and
Enumeration.
Ans:- Iterators differ from enumerations in three
ways:
 Iterators allow the caller to remove elements
from the underlying collection during the
iteration with its remove() method. You can not
add/remove elements from a collection when
using enumerator.
 Enumeration is available in legacy classes i.e
Vector/Stack etc. whereas Iterator is available
in all modern collection classes.
 Another minor difference is that Iterator has
improved method names e.g.
Enumeration.hasMoreElement() has become
Iterator.hasNext(), Enumeration.nextElement()
has become Iterator.next() etc.
24) Difference between Iterator and
ListIterator.
Ans:- There are three Differences are there:
 We can use Iterator to traverse Set and List
and also Map type of Objects. But List Iterator
can be used to traverse for List type Objects,
but not for Set type of Objects.
 By using Iterator we can retrieve the elements
from Collection Object in forward direction only
whereas List Iterator, which allows you to
traverse in either directions using
hasPrevious() and previous() methods.
 ListIterator allows you modify the list using
add() remove() methods. Using Iterator you
can not add, only remove the elements.
25) Difference between ArrayList and
LinkedList.
 Ans:- LinkedList store elements within a
doubly-linked list data structure. ArrayList
store elements within a dynamically resizing
array.
 LinkedList allows for constant-time insertions
or removals, but only sequential access of
elements. In other words, you can walk the list
forwards or backwards, but grabbing an
element in the middle takes time proportional
to the size of the list. ArrayLists, on the other
hand, allow random access, so you can grab
any element in constant time. But adding or
removing from anywhere but the end requires
shifting all the latter elements over, either to
make an opening or fill the gap.
 LinkedList has more memory overhead than
ArrayList because in ArrayList each index only
holds actual object (data) but in case of
LinkedList each node holds both data and
address of next and previous node.
26) How to make a collection read only?
Ans:- Use following methods:
 Collections.unmodifiableList(list);
 Collections.unmodifiableSet(set);
 Collections.unmodifiableMap(map);
These methods takes collection parameter and
return a new read-only collection with same
elements as in original collection.
27) How to make a collection thread safe?
Ans:- Use below methods:
 Collections.synchronizedList(list);
 Collections.synchronizedSet(set);
 Collections.synchronizedMap(map);
Above methods take collection as parameter and
return same type of collection which are
synchronized and thread safe.
28) Why there is no method like
Iterator.add() to add elements to the
collection?
Ans:- The sole purpose of an Iterator is to
enumerate through a collection. All collections
contain the add() method to serve your purpose.
There would be no point in adding to an Iterator
because the collection may or may not be
ordered. And add() method can not have same
implementation for ordered and unordered
collections.
29) What do you understand by iterator fail-
fast property?
Ans:- Fail-fast Iterators fail as soon as they
realized that structure of Collection has been
changed since iteration has begun. Structural
changes means adding, removing or updating any
element from collection while one thread is
Iterating over that collection.
Fail-fast behaviour is implemented by keeping a
modification count and if iteration thread realizes
the change in modification count it throws
ConcurrentModificationException.
30) What do you understand by iterator is
fail-safe?
Ans:- Fail-safe iterators are just opposite to fail-
fast. They never fail if you modify the
underlying collection on which they are
iterating, because they work on clone of
Collection instead of original collection and that’s
why they are called as fail-safe iterator.
Iterator of CopyOnWriteArrayList is an example of
fail-safe Iterator also iterator written by
ConcurrentHashMap keySet is also fail-safe
iterator and never throw
ConcurrentModificationException.
31) How to avoid
ConcurrentModificationException while
iterating a collection?
Ans:- You should first try to find another
alternative iterator which are fail-safe. For
example if you are using List and you can use
ListIterator. If it is legacy collection, you can use
enumeration.
If above options are not possible then you can use
one of three changes:
 If you are using JDK1.5 or higher then you can
use ConcurrentHashMap and
CopyOnWriteArrayList classes. It is the
recommended approach.
 You can convert the list to an array and then
iterate on the array.
 You can lock the list while iterating by putting it
in a synchronized block.
Please note that last two approaches will cause a
performance hit.
32) What is
UnsupportedOperationException?
Ans:- This exception is thrown on invoked
methods which are not supported by actual
collection type.
For example, if you make a read-only list list using
“Collections.unmodifiableList(list)” and then call
add() or remove() method, what should happen. It
should clearly throw
UnsupportedOperationException. This exception is
also thrown when we try to invoke “add()” or
“remove()” methods on fail-safe iterator of
CopyOnWriteArrayList or ConcurrentHashMap.
33) What is the importance of hashCode()
and equals() methods? How they are used
in Java?
Ans:- The java.lang.Object has two methods
defined in it. They are - public boolean
equals(Object obj) public int hashCode(). These
two methods are used heavily when objects are
stored in collections. There is a contract between
these two methods which should be kept in mind
while overriding any of these methods. The Java
API documentation describes it in detail. The
hashCode() method returns a hash code value for
the object. This method is supported for the benefit
of hashtables such as those provided by
java.util.Hashtable or java.util.HashMap. The
general contract of hashCode is: Whenever it is
invoked on the same object more than once during
an execution of a Java application, the hashCode
method must consistently return the same integer,
provided no information used in equals
comparisons on the object is modified. This integer
need not remain consistent from one execution of
an application to another execution of the same
application. If two objects are equal according to
the equals(Object) method, then calling the
hashCode method on each of the two objects must
produce the same integer result. It is not required
that if two objects are unequal according to the
equals(java.lang.Object) method, then calling the
hashCode method on each of the two objects must
produce distinct integer results. However, the
programmer should be aware that producing
distinct integer results for unequal objects may
improve the performance of hashtables. As much
as is reasonably practical, the hashCode method
defined by class Object does return distinct
integers for distinct objects. The equals(Object obj)
method indicates whether some other object is
"equal to" this one. The equals method implements
an equivalence relation on non-null object
references: It is reflexive: for any non-null
reference value x, x.equals(x) should return true. It
is symmetric: for any non-null reference values x
and y, x.equals(y) should return true if and only if
y.equals(x) returns true. It is transitive: for any
non-null reference values x, y, and z, if x.equals(y)
returns true and y.equals(z) returns true, then
x.equals(z) should return true. It is consistent: for
any non-null reference values x and y, multiple
invocations of x.equals(y) consistently return true
or consistently return false, provided no
information used in equals comparisons on the
objects is modified. For any non-null reference
value x, x.equals(null) should return false. The
equals method for class Object implements the
most discriminating possible equivalence relation
on objects; that is, for any non-null reference
values x and y, this method returns true if and only
if x and y refer to the same object (x == y has the
value true). Note that it is generally necessary to
override the hashCode method whenever this
method is overridden, so as to maintain the
general contract for the hashCode method, which
states that equal objects must have equal hash
codes. A practical Example of hashcode() &
equals(): This can be applied to classes that need
to be stored in Set collections. Sets use equals() to
enforce non-duplicates, and HashSet uses
hashCode() as a first-cut test for equality.
Technically hashCode() isn't necessary then since
equals() will always be used in the end, but
providing a meaningful hashCode() will improve
performance for very large sets or objects that
take a long time to compare using equals().

34) What is the difference between


CopyOnWriteArrayList and ArrayList in
Java?
Ans:- a) First and foremost difference
between CopyOnWriteArrayList and ArrayList in
Java is that CopyOnWriteArrayList is a thread-safe
collection while ArrayList is not thread-safe and
cannot be used in multi-threaded environment.

b) Second difference between ArrayList


and CopyOnWriteArrayList is that Iterator of
ArrayList is fail-fast and throw
ConcurrentModificationException once detect any
modification in List once iteration begins but
Iterator of CopyOnWriteArrayList is fail-safe and
doesn't throw ConcurrentModificationException.

c) Third difference
between CopyOnWriteArrayList vs ArrayList is
that Iterator of former doesn't support remove
operation while Iterator of later
supports remove() operation.

35) Which implementation of the List


interface provides for the fastest insertion
of a new element into the middle of the
list?
Ans:- ArrayList and Vector both use an array
to store the elements of the list. When an
element is inserted into the middle of the list
the elements that follow the insertion point
must be shifted to make room for the new
element. The LinkedList is implemented using
a doubly linked list; an insertion requires only
the updating of the links at the point of
insertion. Therefore, the LinkedList allows for
fast insertions and deletions.
36) How do you remove an entry from a
Collection? and subsequently what is
difference between remove() method of
Collection and remove() method of Iterator,
which one you will use, while removing
elements during iteration?

ans:- Collection interface defines


remove(Object obj) method to remove objects
from Collection. List interface adds another
method remove(int index), which is used to
remove object at specific index. You can use
any of these method to remove an entry from
Collection, while not iterating. Things change,
when you iterate. Suppose you are traversing
a List and removing only certain elements
based on logic, then you need to use Iterator's
remove() method. This method removes
current element from Iterator's perspective. If
you use Collection's or List's remove() method
during iteration then your code will throw
ConcurrentModificationException. That's why
it's advised to use Iterator remove() method to
remove objects from Collection.
37) What is difference between
Synchronized Collection and Concurrent
Collection?
Ans:- Java 5 has added several new
Concurrent Collection classes e.g.
ConcurrentHashMap, CopyOnWriteArrayList
etc. Java Also provided way to get
Synchronized copy of collection e.g. ArrayList,
HashMap by using
Collections.synchronizedMap() or
Collections.synchronizedList() Utility functions.
One Significant difference is that Concurrent
Collections has better performance than
synchronized Collection because they lock
only a portion of Map to achieve concurrency
and Synchronization.
38) How does HashSet is implemented in
Java, How does it uses Hashing ?

ans:- This is an interesting issue, because for


hashing you need both key and value
and there is no key for store it in a bucket,
then how exactly HashSet store element
internally. Well, HashSet is built on top of
HashMap. If you look at source code of
java.util.HashSet class, you will find that that it
uses a HashMap with same values for all
keys, as shown below :
private transient HashMap map;

// Dummy value to associate with an Object in


the backing Map
private static final Object PRESENT = new
Object();

When you call add() method of HashSet, it put


entry in HashMap :

public boolean add(E e) {


  return map.put(e, PRESENT)==null;
}

Since keys are unique in a HashMap, it


provides uniqueness guarantee of Set
interface.

39) When do you use ConcurrentHashMap


in Java?
Ans:- ConcurrentHashMap is better suited for
situation where you have multiple readers and one
Writer or fewer writers since Map gets locked only
during write operation .

40) Mention some of the Best Practices of


Collection API.
Ans:- Following are some of the best practices
relating to Java Collection:
a)Use ArrayList, HashMap etc. as
opposed to Vector, Hashtable etc. ,
wherever possible to avoid
synchronization overhead. Even better is
to use just arrays where possible. If
multiple threads concurrently access a
collection and at least one of the threads
either adds or deletes an entry into the
collection , then the collection must be
externally synchronized. This is achieved
by
Map
myMap=Collections.synchronizedMap(myMap
);
List
myList=Collections.synchronizedList(myList);

b) Set the initial capacity of a


collection appropriately (e.g. ArrayList,
HashMap etc.) . This is because
Collection classes like ArrayList, HashMap
etc. must grow periodically to
accommodate new elements. But if you
have a very large array and you know the
size in advance then you can speed things
up by setting the initial size appropriately.
e.g. HashMaps/ Hashtables need to be
created with sufficiently large capacity to
minimize rehashing ( which happens
every time the table grows) . HashMap
has two parameters initial capacity and
load factor that affects its performance and
space requirements. Higher load factor
values ( default load factor of 0.75
provides a good trade off bet’n
performance and space) will reduce the
space cost but will increase the lookup
cost of myMap.get(….) and
myMap.put(….) methods . When the
number of entries in the HashMap
exceeds the current capacity * load
factor then the capacity of HashMap is
roughly doubled by calling the rehash
function. It is also very important not to set
the initial capacity too high or load factor
too low if iteration performance or
reduction in space is important.

C) Program in terms of interface not


implementation: for example you might
decide a LinkedList is the best choice for
some application, but then later decide
ArrayList might be a better choice for
performance reason.
Use:
List list=new ArrayList(100);
Instead of
ArrayList arr=new ArrayList();

d) Return zero length collections or


arrays as opposed to returning null :
returning null instead of zero length
collection ( use Collections.EMPTY_SET,
Collections.EMPTY_LIST,Collections.EMP
TY_MAP) is more error-prone, since the
programmer writing the calling method
might forget to handle a return value of
null.
e)Immutable objects should be used as
keys for the HashMap: generally you
use a java.lang.Integer or java.lang.String
class as the key, which are immutable
Java objects. If you define your own key
class then it is a best practice to make the
key class an immutable object ( i.e. do not
provide any “setter” methods .
f) Encapsulate collections : in general
collections are not immutable objects. So
care should be taken not to unintentionally
expose the collection fields to the caller.
Avoid
The following code snippet exposes the
Set “setCars” directly to the caller. This
approach is riskier because the variable “cars”
can be modified unintentionally.
public class CarYard
{
private Set<Car> cars=new
HashSet<Car>();

// exposes the cars to the caller


public Set<Car> getCars()
{
return cars;
}

// exposes the cars to the caller


public void setCars(Set<Car> cars)
{
this.cars=cars;
}
}

Better approach
This approach prevents the caller from
directly using the underlying variable “cars”.

public class CarYard


{
private Set<Car> cars=new
HashSet<Car>();
public void addCar(Car car)
{
cars.add(car);
}
public void removeCar(Car car)
{
cars.remove(car);
}

public Set<Car> getCars()


{
// use factory method from the
Collections
return
Collections.unmodifiableSet(cars);
}

}
41) What is hash collision? How does map
implementations deal with it?
Ans:- When two or more different keys
produce the same hash value, it’s called a
Hash Collision. A map implementation deals
with collisions by storing all the key/object
pairs that have the same hash value in a same
bucket ( i.e. in the form of linked list).
Retrieving an object that resulted in a collision
when it was stored is a two-step process. The
key will be hashed to find the location where
the key/object pair should be. The linked list
then has to be searched to sort out the
particular key you are searching on from all
others that have the same hash value.
42) What is the difference between “put()”
method of Map vs “add()” method of Set?
Ans:- “put” method of Map
* If the map previously contained a mapping for
the key, the old
* value is replaced.
public V put(K key, V value) { …….. }
“add” method of Set
* Adds the specified element to this set if it is
not already present.
* If this set already contains the element, the call
leaves the set
* unchanged and returns false.
public boolean add(E e) {}

43) How does “put()” method of map


actually works?
Ans:-
-- First of all, key object is checked for null. If key is
null, value is stored in table[0] position. Because
hash code for null is always 0.

-- Then on next step, a hash value is calculated


using key’s hash code by calling its hashCode()
method. This hash value is used to calculate index
in array for storing Entry object. JDK designers
well assumed that there might be some poorly
written hashCode() functions that can return very
high or low hash code value. To solve this issue,
they introduced another hash() function, and
passed the object’s hash code to this hash()
function to bring hash value in range of array index
size.
-- Now indexFor(hash, table.length) function is
called to calculate exact index position for storing
the Entry object.
-- Here comes the main part. Now, as we know
that two unequal objects can have same hash
code value, how two different objects will be stored
in same array location [called bucket].
Answer is LinkedList. If you remember, Entry class
had an attribute “next”. This attribute always
points to next object in chain. This is exactly the
behaviour of LinkedList.
So, in case of collision, Entry objects are stored in
LinkedList form. When an Entry object needs to be
stored in particular index, HashMap checks
whether there is already an entry?? If there is no
entry already present, Entry object is stored in this
location.

If there is already an object sitting on calculated


index, its next attribute is checked. If it is null, and
current Entry object becomes next node in
LinkedList. If next variable is not null, procedure is
followed until next is evaluated as null.

44) What if we add the another value


object inside map with same key (with
matching hashcode and equals) as entered
before?
Or
How do map implementations ensure the
uniqueness of keys?
Ans:- Logically, it should replace the old value.
How it is done? Well, after determining the index
position of Entry object, while iterating over
LinkedList on calculated index, HashMap calls
equals method on key object for each Entry object.
All these Entry objects in LinkedList will have
similar hash code but equals() method will test for
true equality. If newkey.equals(existingkey) will
be true then both keys are treated as same key
object. This will cause the replacing of value object
inside Entry object only.
In this way, map implementations ensure the
uniqueness of keys.

45) Why ListIterator has add() method but


Iterator doesn't or Why add() method is
declared in ListIterator and not on Iterator.
Ans:- ListIterator has add() method because of its
ability to traverse or iterate in both direction of
collection. it maintains two pointers in terms of
previous and next call and in position to add new
element without affecting current iteration.

46) When does


ConcurrentModificationException occur on
iteration?
Ans:- When you remove or add object using
Collection's or List's add or remove method e.g.
add(Object element), remove(Object element) or
remove(int index), instead of Iterator's remove()
method than ConcurrentModificationException
occur. As per Iterator's contract, if it detect any
structural change in Collection e.g. adding or
removing of element, once Iterator begins, it can
throw ConcurrentModificationException. 

47) Difference between ArrayList and


LinkedList.
Ans:- following are some of the imp points:
a) Adding new elements is pretty fast for either
type of list
b)For the ArrayList, doing random lookup using
"get" is fast, but for LinkedList, it's slow. It's
slow because there's no efficient way to index
into the middle of a linked list. Linkedlist
lookup always start from 1st location.
c) When removing and inserting elements in
between , using ArrayList is slow. This is
because all remaining elements in the
underlying array of Object instances must be
shifted down for each removal or insertion
operation. But LinkedList is fast, because
deletion or insertion can be done simply by
changing a couple of links.
So an ArrayList works best for cases where
you're doing random access on the list or
adding at the end and a LinkedList works
better if you're doing a lot of insertion or
removal in the middle of the list.

48) What is the difference between


comparator and comparable in java?

Ans:- Comparable
A comparable object is capable of comparing
itself with another object. The class itself must
implements the java.lang.Comparable
interface in order to be able to compare its
instances.

Comparator
A comparator object is capable of comparing
two different objects. The class is not
comparing its instances, but some other
class’s instances. This comparator class must
implement the java.util.Comparator interface.

Comparable and Comparator both are used


for sorting the collection. Comparable provides
only one sorting strategy whereas Comparator
provides multiple sorting strategies.
For example, support ArrayList contains 100
Employee objects that have id, name, salary etc. If
you want to sort the arraylist object based on id or
name or salary, you should use Comparable
interface. But if you want to sort the ArrayList
object based on id then name then salary, you
should use Comparator interface.

Implementing Comparable means "I can compare


myself with another object." This is typically useful
when there's a single natural default comparison.
Implementing Comparator means "I can compare
two other objects." This is typically useful when
there are multiple ways of comparing two
instances of a type - e.g. you could compare
people by age, name etc.

49) What is CopyOnWriteArrayList?

Ans:- A thread-safe variant of ArrayList in which


all mutative operations (add, set, and so on) are
implemented by making a fresh copy of the
underlying array.
This is ordinarily too costly, but may
be more efficient than alternatives when traversal
operations vastly outnumber mutations, and is
useful when you cannot or don't want to
synchronize traversals, yet need to preclude
interference among concurrent threads. The
"snapshot" style iterator method uses a reference
to the state of the array at the point that the iterator
was created. This array never changes during the
lifetime of the iterator, so interference is impossible
and the iterator is guaranteed not to
throw ConcurrentModificationException. The
iterator will not reflect additions, removals, or
changes to the list since the iterator was created.
Element-changing operations on iterators
themselves (remove, set, and add) are not
supported. These methods
throwUnsupportedOperationException.
50) Explain ConcurrentHashMap in java.
Ans:-    ConcurrentHashMap is introduced as
an alternative of Hashtable and provided all
functions supported by Hashtable with additional
feature called "concurrency level", which
allows ConcurrentHashMap to partition Map.
ConcurrentHashMap allows multiple readers to
read concurrently without any blocking. This
is achieved by partitioning Map into different parts
based on concurrency level and locking only a
portion of Map during updates. Default
concurrency level is 16, and accordingly Map is
divided into 16 part and each part is governed with
different lock. This means, 16 thread can operate
on Map simultaneously, until they are operating on
different part of Map. This
makes ConcurrentHashMap high performance
despite keeping thread-safety intact.  Though, it
comes with limitation. Since update operations
like put(), remove(), putAll() or clear() is
not synchronized, concurrent retrieval may not
reflect most recent change on Map.

In case of putAll() or clear(), which operates on


whole Map, concurrent read may reflect insertion
and removal of only some entries. Another
important point to remember is iteration over
CHM, Iterator returned by keySet of ConcurrentHa
shMap are weakly consistent and they only reflect
state of ConcurrentHashMap and certain point and
may not reflect any recent change. Iterator
of ConcurrentHashMap's keySet area also fail-
safe and doesn’t
throw ConcurrentModificationExceptoin..

Default concurrency level is 16 and can be


changed, by providing a number which make
sense and work for you while creating
ConcurrentHashMap. Since concurrency level is
used for internal sizing and indicate number of
concurrent update without contention, so, if you
just have few writers or thread to update Map
keeping it low is much better. ConcurrentHashMap
also uses ReentrantLock to internally lock its
segments.
some more info about ConcurrentHashMap:
The definition of Segment is as below:

    /**
     * Inner Segment class
     * Plays a significant role
     */
    protected static final class Segment {
        protected int count;

        protected synchronized int getCount() {


            return this.count;
        }

        protected synchronized void synch() {}


    }
    
    /** Segment Array declaration **/
    public final Segment[] segments = new
Segment[16];
    
    
As we all know that Map is a kind of data structure
which stores data in key-value pair which is array
of inner class Entry, see as below:
    static class Entry implements Map.Entry {
        
        protected final Object key;
        protected volatile Object value;
        protected final int hash;
        protected final Entry next;

        Entry(int hash, Object key, Object value,


Entry next) {
            
            this.value = value;
            this.hash = hash;
            this.key = key;
            this.next = next;
        }
        
        // Code goes here like getter/setter 
    }
    
And ConcurrentHashMap class is having an array
defined as below of type Entry class:

    protected transient Entry[] table;


    
And this Entry array is getting initialized when we
are creating an instance of ConcurrentHashMap
even using default constructor as default
constructor called this constructor internally as
below:

    public ConcurrentHashMap(int initialCapacity,


float loadFactor) {
        
        //Some code
        int cap = getCapacity();
        this.table = newTable(cap); // here this.table
is Entry[] table
    }
    
    protected Entry[] newTable(int capacity) {
        this.threshold = ((int)(capacity *
this.loadFactor / 16.0F) + 1);
        return new Entry[capacity];
    }
    
Here threshold is getting initialized for re-sizing
purpose.
   
Inserting (Put) element in
ConcurrentHashMap:-
Most important thing to understand the put method
of ConcurrentHashMap, that how
ConcurrentHashMap works when we are adding
the element. As we know put method takes two
arguments both of type Object as below:

    put(Object key, Object value)


    
So it wil 1st calculate the hash of key as below:

    int hashVal = hash(key);


    
    static int hash(Object x) {
        int h = x.hashCode();
        return (h << 7) - h + (h >>> 9) + (h >>> 17);
    }
        
After getting the hashVal we can decide the
Segment as below:

    Segment seg = segments[(hash & 0x1F)];     //


segments is an array defined above
    
Since its all about concurrency definetely we need
synchronized block on the above Segment seg as
below:

    synchronized (seg) {


     // code to add 
    
        int index = hash & table.length - 1; // hash we
have calculated for key and table is Entry[] table
        Entry first = table[index];
        for (Entry e = first; e != null; e = e.next) {
            if ((e.hash == hash) && (eq(key, e.key)))
{ // if key already exist means updating the value
                Object oldValue = e.value;
                e.value = value;
                return oldValue;
            }
        }
        
        Entry newEntry = new Entry(hash, key, value,
first); // new entry, i.e. this key not exist in map
        table[index] = newEntry;                             //
Putting the Entry object at calculated Index  
    }

Size of ConcurrentHashMap:- 
    
Now when we are asking for size() of the
ConcurrentHashMap the size comes as below:

    for (int i = 0; i < this.segments.length; i++) {


            c += this.segments[i].getCount();        
//here c is an integer initialized with zero
    }    

Getting element from ConcurrentHashMap:-

when we are getting an element from


ConcurrentHashMap we are simply passing key
and hash of key is getting calculated. The defintion
goes something like as below:

    public Object get(Object key){


        //some  code here
        
        int index = hash & table.length - 1;  //hash we
have calculated for key and calculating index with
help of hash
        Entry first = table[index];                         
//table is Entry[] table
        for (Entry e = first; e != null; e = e.next) {
            if ((e.hash == hash) && (eq(key, e.key))) {
                Object value = e.value;
                if (value == null) {
                    break;
                }
                return value;
            }
        }
        //some  code here
    }
    
Note: No need to put any lock when getting the
element from ConcurrentHashMap.

Removing element from ConcurrentHashMap:-

Now question is how remove works with


ConcurrentHashMap, so let us understand it.
Remove basically takes one argument 'Key' as an
argument or takes two argument 'Key' and 'Value'
as below:
    
    Object remove(Object key);
    boolean remove(Object key, Object value);
    
Now let us understand that how internally it works.
The method remove(Object key) internally calls
remove(Object key, Object value) where it passed
'null' as value. since we are going to remove an
element from a Segment definitely we need a lock
on the respected Segment.

    Object remove(Object key, Object value) {


    
        Segment seg = segments[(hash & 0x1F)];   //
hash we have calculated for key
    
        synchronized (seg) {
            Entry[] tab = this.table;                //table is
Entry[] table     
            int index = hash & tab.length - 1;      
//calculating index with help of hash
            Entry first = tab[index];                //Getting
the Entry Object
            
            Entry e = first;
            while(true) {
                if ((e.hash == hash) && (eq(key, e.key)))
{
                    break;
                }
                e = e.next;
            }
            Object oldValue = e.value;
            Entry head = e.next;
            for (Entry p = first; p != e; p = p.next) {
                head = new Entry(p.hash, p.key,
p.value, head);
            }
            table[index] = head;
            seg.count -= 1;
        }
        return oldValue;
    }
51) What is bucket ? 

Ans:- A bucket is used to store key value pairs


. A bucket can have multiple key-value pairs .
In hash map, bucket used simple linked list to
store objects .

52) How will you retrieve Value object from


map implementations if two Keys will have
same hashcode?
ans:- first we will call get() method and
then HashMap uses Key Object's hashcode to
find out bucket location. After finding bucket
location , we will call keys.equals() method to
identify correct node in LinkedList and return
associated value object for that key in
Java HashMap .

53) draw the picture of entry table in case


of map implementations.
Ans:-
53) What happens On HashMap in Java if
the size of the HashMap  exceeds a given
threshold defined by load factor ?

ans:- If the size of the Map exceeds a given


threshold defined by load-factor e.g. if load
factor is .75 it will act to re-size the map once it
filled 75%. Similar to other collection classes
like ArrayList,  Java HashMap re-size itself by
creating a new bucket array of size twice of
previous size of HashMap , and then start
putting every old element into that new bucket
array. This process is
called rehashing because it also applies hash
function to find new bucket location. 

54) What do you mean by rehashing in


case of map implementations?
Ans:- When the size of the Map exceeds a
given threshold defined by load-factor e.g. if
load factor is .75 it will act to re-size the map
once it filled 75%. Map re-sizes itself by
creating a new bucket array of size twice of
previous size of map , and then start putting
every old element into that new bucket array.
This process is called as rehashing .

53) Why String, Integer and other wrapper


classes are considered good keys?
ans:- String, Integer and other wrapper
classes are natural candidates
of HashMap key, and String is most frequently
used key as well because String is immutable
and final,and
overrides equals and hashcode() method.
Other wrapper class also shares similar
property. Immutabiility is required, in order to
prevent changes on fields used
to calculate hashCode() because if key object
return different hashCode during insertion and
retrieval than it won't be possible to get object
from HashMap. Immutability is best as it offers
other advantages as well like thread-safety, If
you can  keep your hashCode same by only
making certain fields final, then you go for that
as well.
Since equals() and hashCode() method is
used during reterival of value object
from HashMap, it’s important that key object
correctly override these methods and follow
contact. If unequal object return different
hashcode than chances of collision will be less
which subsequently improve performance of
HashMap.
54) How does map resolves collision?
Ans:- When we call put method by passing key-
value pair, “put” method invokes “hash()” method
on Key hashCode() and finds out the index to
store the key-value pair. Now when u put another
entry, there are two scenarios of hash collision:
a)Hashcode of the given entry is same as
existing entry/entries. – in this case == is
called on key, if it matches, it overwrites
the value. If == doesn’t match, then
“equals()” is invoked ,if it returns true then
overwrites the value. If not linked list is
formed.
b) Hashcode of the given entry is different
from the existing keys in the map, but
index returned from the “hash()” is same
as that of existing entries. – in this case
also linked list is formed.
a and b prove that hash collision can
happen in two cases ie. When hashcode is
same as existing entries or when
hashcode is different but index is same as
that of existing entries.
When we call get method by passing Key,
again it uses “hash()” function which uses the
hashCode() of given key to find the index in
the array and then uses ==. If == returns true,
it returns the value , if it returns false,then
equals() method is invoked , if it returns true
value is returned otherwise next node inside
the linkedlist is traversed to find the correct
Entry and return it’s value.

55) How do you traverse through a


collection using its Iterator?
Ans:- To use an iterator to traverse through the
contents of a collection, follow these steps:
 Obtain an iterator to the start of the collection
by calling the collection implementation’s
iterator() method.
 Set up a loop that makes a call to hasNext().
Have the loop iterate as long as hasNext()
returns true.
 Within the loop, obtain each element by calling
next().

60) What are the advantages of ArrayList


over arrays ?
Ans:- Some of the advantages ArrayList has over
arrays are:
 It can grow dynamically
 It provides more powerful insertion and search
mechanisms than arrays.
61)Why insertion and deletion in ArrayList
is slow compared to LinkedList ?
 Ans:- ArrayList internally uses and array to
store the elements, when that array gets filled
by inserting elements a new array of roughly
1.5 times the size of the original array is
created and all the data of old array is copied
to new array.
 During deletion, all elements present in the
array after the deleted elements have to be
moved one step back to fill the space created
by deletion. In linked list data is stored in
nodes that have reference to the previous
node and the next node so adding element is
simple as creating the node an updating the
next pointer on the last node and the previous
pointer on the new node. Deletion in linked list
is fast because it involves only updating the
next pointer in the node before the deleted
node and updating the previous pointer in the
node after the deleted node.
62) Why are Iterators returned by ArrayList
called Fail Fast ?
Ans:- Because, if list is structurally modified at any
time after the iterator is created, in any way except
through the iterator's own remove or add methods,
the iterator will throw a
ConcurrentModificationException. Thus, in the
face of concurrent modification, the iterator fails
quickly and cleanly, rather than risking arbitrary,
non-deterministic behavior at an undetermined
time in the future.
63) How do you decide when to use
ArrayList and When to use LinkedList?
Ans:- If you need to support random access,
without inserting or removing elements from any
place other than the end, then ArrayList offers the
optimal collection. If, however, you need to
frequently add and remove elements from the
middle of the list and only access the list elements
sequentially, then LinkedList offers the better
implementation.
64) Difference between ArrayList and
Vector.
Ans:-

ArrayList Vector
ArrayList is NOT Vector List is
synchronized by default. synchronized by default.
Vector list can use
ArrayList can use only
Iterator and Enumeration
Iterator to access the
Interface to access the
elements.
elements.

65) explain Collection API hierarchy.


66) What is the difference between
Enumerator, Iterator and ListIterator?
Ans:-

Propert Enumeration Iterator ListIterator


y
Numbe 2 3 9
r of
method
Method hasMoreElemen hasNext( add(),
names ts(), ), next(), hasNext(),
nextElement() remove() next(),
. hasPrevious(
), previous(),
nextIndex(),
previousInde
x(),
set(),remove
().
Access Forward-only Forward Bi-directional
Directio only
n
Summa It provides a Iterator It provides a
ry read only provides bi-directional
traversal of the a access on
collection. method the collection
Legacy classes to and hence
such as Vector remove has methods
and an to support it,
HashTable’s element like
methods returns from the previous()
this iterator. and next(). It
Java also allows
Collectio the
n modification
Framew of elements
ork using set()
classes and add()
methods operation.
return
this.
67) what is the difference between
Hashtable and ConcurrentHashMap?
Ans:- both can be used in multithreaded
environment but once the size of hashtable
becomes considerable large, performance
degrade because for iteration it has to be locked
for longer duration.

Since ConcurrentHashMap introduced concept of


segmentation , how large it becomes only certain
part of it get locked to provide thread safety so
many other readers can still access map without
waiting for iteration to complete.

In Summary ConcurrentHashMap only locked


certain portion of Map while Hashtable lock full
map while doing iteration.
68) What is the difference between
Synchronized Collection classes and
Concurrent Collection Classes ?
Ans:- The synchronized collections classes,
Hashtable and Vector, and the synchronized
wrapper classes,
Collections.synchronizedMap and
Collections.synchronizedList, provide a basic
conditionally thread-safe implementation of
Map and List.
However, several factors make them
unsuitable for use in highly concurrent
applications -- their single collection-wide lock
is a hurdle to scalability and it often becomes
necessary to lock a collection for a
considerable time during iteration to prevent
ConcurrentModificationExceptions.

The ConcurrentHashMap and


CopyOnWriteArrayList implementations
provide much higher concurrency while
preserving thread safety, with some minor
compromises in their promises to callers.
ConcurrentHashMap and
CopyOnWriteArrayList are not necessarily
useful everywhere you might use HashMap or
ArrayList, but are designed to optimize specific
common situations. Many concurrent
applications will benefit from their use.
69) what is the drawback of synchronized
collections classes, Hashtable and Vector,
and the synchronized wrapper classes,
Collections.synchronizedMap and
Collections.synchronizedList etc. ?
Ans:- The simple approach to synchronization
taken by both Hashtable and synchronizedMap --
synchronizing each method on the Hashtable or
the synchronized Map wrapper object -- has two
principal deficiencies. It is an obstacle to
scalability, because only one thread can access
the hash table at a time. At the same time, it is
insufficient to provide true thread safety, in that
many common compound operations still require
additional synchronization. While simple
operations such as get() and put() can complete
safely without additional synchronization, there are
several common sequences of operations, such as
iteration or put-if-absent, which still require
external synchronization to avoid data races.

70) what is heap pollution?

Ans:- heap pollution is a situation that arises


when a variable of a parameterized type refers to
an object that is not of that parameterized
type.This situation is normally detected during
compilation and indicated with an unchecked
warning. Later, during runtime heap pollution will
often cause a ClassCastException. Consider
following example:

List ln = new ArrayList<Number>();


ln.add(10);
List<String> ls =ln; // unchecked warning
String s = ls.get(0); // ClassCastException
System.out.println(s);

After the assignment of the reference variable  ln


to the reference variable ls , the  List<String>
variable will point to a  List<Number> object. Such
a situation is called  heap pollution and is usually
indicated by an unchecked warning.  A polluted
heap is likely to lead to an unexpected 
ClassCastException at runtime.  In the example
above, it will lead to a  ClassCastException , when
a object is retrieved from the  List<String> and
assigned to a  String variable, because the object
is a  Number , not a String .

71) even after creating


Collections.synchronizedList(new
ArrayList()), why do we need to use
“synchronized” block?
Ans:- a) If you only access your list using
elementary operations (add(), remove(), etc)
and invocations of these operations don't
depend on each other (i.e. atomicity is not an
issue), you can use
only synchronizedList() without
explicit synchronized blocks
b)If you want to be able to invoke
elementary operations
without synchronized blocks, but also have
compound operations (including iteration)
that should be atomic, you need
both synchronizedList() and synchronized 
blocks for compound operations.
72) discuss the problem of thread-safety
with synchronized collection classes as
well as synchronized wrapper classes.
Ans:- both are thread safe. As their individual
methods are synchronized.
I.e.
Vector myvect=new Vector();
or
List list = Collections.synchronizedList(new
ArrayList(...));

In java.util.Collections' JavaDoc you can read


that "It is imperative
that the user manually synchronize on the
returned list or vector when iterating
over it:"

synchronized(list) {
Iterator i = list.iterator(); // Must be in
synchronized block
while (i.hasNext())
foo(i.next());
}
Now if synchronizedList gives me a thread-
safe List implementation , why do I need to
use explicit synchronization?

Vector and synchronizedList() both end up


synchronizing each individual method call - but
they do not provide any protection against other
threads changing the thread in between individual
method calls. So any time you rely on some sort
of consistent state in between two method calls,
there is a possibility of failure. 

For example: 
1.for (Foo f : fooVector) {  
2.  doSomethingWith(f);  
3.}  

1.Iterator<Foo> it = fooVector.iterator();  
2.while (it.hasNext()) {  
3.  Foo f = (Foo) it.next();  
4.  doSomethingWith(f);  
5.}  

OK, that's normal enough. But if fooVector is also


accessible to other threads which can modify it,
problems can occur. What happens if something
changes in between the calls to it.hasNext() and
it.next()? 
1.Iterator<Foo> it = fooVector.iterator();  
2.while (it.hasNext()) {  
3.  // other thread calls fooVector.remove(0)  
4.  Foo f = (Foo) it.next(); // now this line may thr
ow NoSuchElementException  
5.  doSomethingWith(f);  
6.}  

To avoid this problem, it's necessary to


synchronize as described in the List.iterator() API: 
1.synchronized (fooVector) {  
2.  Iterator<Foo> it = fooVector.iterator();  
3.  while (it.hasNext()) {  
4.    Foo f = (Foo) it.next();  
5.    doSomethingWith(f);  
6.  }  
7.}  

But this problem is not limited to use of Iterators.


Here's another example: 
1.if (!fooVector.isEmpty()) {  
2.  Foo f = fooVector.remove(0);  
3.  doSomethingWith(f);  
4.}  

Here, again - what if, in between the isEmpty() and


the remove(0), another thread removes the only
element in fooVector? You get a
NoSuchElementException. 

Or a more common example, getting the last


element of a List: 
1.Foo lastFoo = fooList.get(fooList.size() - 1);  

The call to fooList.size() must execute before


fooList.get(). What happens if a single element
is removed from the list, in between these two
operations? NoSuchElementException. Or if a
single element is added, anywhere in the list
(except the very end)- oops, you just got the
next-to-last element, rather than the last one. 

To summarize, Both synchronized collection


classes and synchronized wrapper classes
seem to give people a false sense of
confidence that their code is thread-safe, when
it really isn't. Additional synchronization is
almost always needed
76) what is the requirement of putting any key
inside TreeMap or element inside TreeSet?
Ans:- Whether u want to put any key inside
TreeMap or element inside TreeSet u need to fulfil
one of the following requirements:
a)Key must implement “Comparable”
interface so that u will define
“compareTo(Object)” method and provide
the strategy to compare a particular field.
b)If key is not implementing “Comparable”,
then u need to create an implementation
of “Comparator” by defining
“compare(Object,Object)” to provide the
strategy to compare a particular field. Now
pass this Comparator implementation to
TreeMap or TreeSet constructor. When u
put a key inside TreeMap or add an
element inside TreeSet, outcome of
compare() method will be considered.

77) what is the difference between C++


class template and Java Generics?
Ans:-
1. In C++ templates, parameters can be any type or integral but in Java, parameters can only be
reference types (not primitive types).

1 std::map<int, int> mapping;


1 Map<Integer, Integer> mapping;

2. For C++ templates, Separate copies of the


class or function are likely to be generated for
each type parameter when compiled (this is also
known as “template code bloat”). However for
Java generics, only one version of the class or
function is compiled and it works for all type
parameters.
3. For C++ templates, Implementation source
code of the template class or function must be
included in order to use it (declaration
sufficient). For Java templates, Signature of the
class or function from a compiled class file is
sufficient to use it.
4. C++ templates can be specialized - a separate
implementation could be provided for a
particular template parameter. In Java, generics
cannot be specialized.

You might also like