Collections Interview questions

1. What can cause java.util.concurrentmodificationexception ?

The ConcurrentModificationException is a RuntimeException that may be thrown by methods that have detected concurrent modification of an object, when such modification is not permissible. An example of not permissible behavior is when a thread tries to modify the internal structure of a Collection, while another thread is iterating over it.

The results of the iteration are undefined. Some iterators throw a ConcurrentModificationException when they detect such behavior. These iterators are called fail-fast iterators, as they stop the normal execution and report an error, rather than continuing in a non-deterministic way. Notice that this exception does not indicate that the object has been concurrently modified by a different thread.

There could be below cases which can cause ConcurrentModificationException –

Case 1: Collection is modified internally while iterating over it

/**
ConcurrentModification Exception Case1 example
*
*/
package com.myjavablog.javainterview.concurrentmodificationexception;

import java.util.HashMap;
import java.util.Map;

public class CMException_Case1 {

public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();

// Insert some sample key-value pairs.
map.put("KEY1", 10);
map.put("KEY2", 20);
map.put("KEY3", 30);

/* Remove a value of the map, while iterating over it.
* The following code throws a java.util.ConcurrentModificationException. */
for(String key: map.keySet()) {
if(map.get(key) == 10)
map.remove(key);
}
System.out.println("Successfully removed a pair!");
}
}

Output:

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1437)
at java.util.HashMap$KeyIterator.next(HashMap.java:1461)
at com.myjavablog.javainterview.concurrentmodificationexception.CMException_Case1.main(CMException_Case1.java:22)

This exception came because we removed the element from HashMap while iterating through it.

Case 2: After the creation of an iterator, the Collection is internally modified by any method other than the iterator’s own methods for removal and addition.

/**
ConcurrentModification Exception Case2 example
*
*/
package com.myjavablog.javainterview.concurrentmodificationexception;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class CMException_Case2 {

public static void main(String[] args) {

List<String> list = new ArrayList<String>();

// Insert some sample values.
list.add("VALUE1");
list.add("VALUE2");
list.add("VALUE3");

// Get an iterator.
Iterator<String> ite = list.iterator();

/*
* Remove the first object of the list. This statement will force the iterator
* to throw a ConcurrentModificationException.
*/
list.remove(0);

while (ite.hasNext())
System.out.println(ite.next());
}
}

Output:

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1437)
at java.util.HashMap$KeyIterator.next(HashMap.java:1461)
at com.myjavablog.javainterview.concurrentmodificationexception.CMException_Case1.main(CMException_Case1.java:22)

This exception came because we removed the element from list rather than using iterator’s own remove method.

Case 3: Two iterators simultaneously modify the internal structure of a Collection.

/**
ConcurrentModification Exception Case3 example
*
*/
package com.myjavablog.javainterview.concurrentmodificationexception;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class CMException_Case3 {

public static void main(String[] args) {
List<String> list = new ArrayList<String>();

// Insert some sample values.
list.add("VALUE1");
list.add("VALUE2");
list.add("VALUE3");

// Get two iterators.
Iterator<String> ite = list.iterator();
Iterator<String> ite2 = list.iterator();

// Point to the first object of the list and then, remove it.
ite.next();
ite.remove();

/* The second iterator tries to remove the first object as well. The object does
* not exist and thus, a ConcurrentModificationException is thrown. */
ite2.next();
ite2.remove();}
}

Output:

Exception in thread "main" java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1437)
at java.util.HashMap$KeyIterator.next(HashMap.java:1461)
at com.myjavablog.javainterview.concurrentmodificationexception.CMException_Case1.main(CMException_Case1.java:22)

This exception came because , 1st iterator modifies the internal structure of the list, by removing its first object. The 2nd iterator tries to remove the first object as well, but the first object does not exist and thus, a ConcurrentModificationException is thrown.

2. How to get rid of ConcurrentModificationException collections ?

  • Synchronization

In order to avoid more than one threads accessing or modifying the same object, you can synchronize them over the object, in order to allow only one thread to manipulate it over the time. However, notice that this approach may reduce the performance of your application, or create deadlocks, if the application has not been developed carefully.

  • Synchronized Collections

In addition to their default implementations, Java provides a synchronized implementation of a Map, a List, a Set, a Collection, etc. through the Collections class. Moreover, Java provides the CopyOnWriteArrayList class, in which all mutative operations are implemented by making a fresh copy of the underlying array. Finally, Java also provides the ConcurrentHashMap class, which offers full concurrency of retrievals and adjustable expected concurrency for updates.

All referenced implementations are thread safe. However, the usage of such data structures may also reduce the performance of your application, as thread synchronization spends CPU cycles.

  • Iterator’s remove method

In a single-threaded environment, use the iterator’s remove method, in order to concurrently iterate over a collection and remove things from it.

Example:

/**
How to avoid ConcurrentModification Exception
*
*/

package com.myjavablog.javainterview.concurrentmodificationexception;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class CMException_Solution {

public static void main(String[] args) {
List<String> list = new ArrayList<String>();

// Insert some sample values.
list.add("VALUE1");
list.add("VALUE2");
list.add("VALUE3");

// Get iterator.
Iterator<String> ite = list.iterator();

while(ite.hasNext()) {
String value = ite.next();
if(value.equals("VALUE1") )
ite.remove();
else
System.out.println(value);
}
}
}

3. What do you understand by iterator fail-fast property?

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.

4. What is difference between fail-fast and fail-safe?

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.

5. How to avoid ConcurrentModificationException while iterating a collection?

We can use concurrent collection classes to avoid ConcurrentModificationException while iterating over a collection,

Example CopyOnWriteArrayList instead of ArrayList, ConcurrentHashMap instead of HashMap.

6. What is the importance of hashCode() and equals() methods?

HashCode and Equals methods in java

7. What is the output for below program?

package com.myjavablog.javainterview.collections;

import java.util.HashSet;

class City {
private String name;

City(String name) {
this.name = name;
}

public String toString() {
return name;
}
}

public class CollectionQuiz1 {

public static void main(String[] str) {
HashSet myMap = new HashSet();
String s1 = new String("Mumbai");
String s2 = new String("Mumbai");
City s3 = new City("Pune");
City s4 = new City("Pune");
myMap.add(s1);
myMap.add(s2);
myMap.add(s3);
myMap.add(s4);
System.out.println(myMap);
}
}

Output:

[Pune, Pune, Mumbai]

Explaination:

As string class has hashcode() and equals() methods overridden in it, s1 and s2 object has same hashcode and equals method will also return true so duplicate string will be discarded . But in case of custom City objects , we don’t have hashcode() and equals() methods implemented in it. So two city objects are pointing to different memory addresses and thus considered different and will be inserted into Set.

Please refer for more information – HashCode and Equals methods in java

8. What is the output for below program?

package com.myjavablog.javainterview.collections;

import java.util.HashSet;

public class Student {
public String name;

@Override
public int hashCode() {
return 27;
}

@Override
public boolean equals(Object obj) {
return true;
}

public static void main(String args[]) {
Student StudentOne = new Student();
Student StudentTwo = new Student();
Student StudentThree = new Student();
StudentOne.name = "John";
StudentTwo.name = "Darren";
StudentThree.name = "Simon";

HashSet StudentSet = new HashSet();
StudentSet.add(StudentOne);
StudentSet.add(StudentTwo);
StudentSet.add(StudentThree);
System.out.println(StudentSet.size());
}
}

Output:

1

Explaination:

Here hashcode() method always return same hashcode i.e. 27 and equals() always return true. This means ,we can not differentiate between these objects and all are considered same. So we will have only one object at the end even if we add as many objects in Set.

Please refer for more information – HashCode and Equals methods in java

 

7. Can we add elements to collections if it is declared as final?

Question arises to our mind whether we can add elements to collection defined as final. As we can’t modify the variable defined as final. Lets see below example –

/**
Adding elements to final Collection
*
*/
package com.myjavablog.javainterview.concurrentmodificationexception;

import java.util.ArrayList;
import java.util.List;

public class FinalCollection {

public static void main(String[] args) {

final List<String> list = new ArrayList<>();

list.add("Test1");
list.add("Test2");
list.add("Test3");
list.add("Test4");

System.out.println(list);
}

// We try to add list1 reference to final list
List<String> list1 = new ArrayList<>();
list1.add("Test5");
list1.add("Test6");

list = list1;

}

Output: First sysout will print below –

[Test1, Test2, Test3, Test4]

When we try to add list1 reference to final list below compile time exception will be shown –

The final local variable list cannot be assigned. It must be blank and not using a compound assignment

8. What is difference between HashMap and Hashtable?

HashMap and Hashtable both implements Map interface and looks similar, however there are following difference between HashMap and Hashtable.

  1. HashMap allows null key and values whereas Hashtable doesn’t allow null key and values.
  2. Hashtable is synchronized but HashMap is not synchronized. So HashMap is better for single threaded environment, Hashtable is suitable for multi-threaded environment.
  3. LinkedHashMap was introduced in Java 1.4 as a subclass of HashMap, so incase you want iteration order, you can easily switch from HashMap to LinkedHashMap but that is not the case with Hashtable whose iteration order is unpredictable.
  4. HashMap provides Set of keys to iterate and hence it’s fail-fast but Hashtable provides Enumeration of keys that doesn’t support this feature.
  5. Hashtable is considered to be legacy class and if you are looking for modifications of Map while iterating, you should use ConcurrentHashMap.

9. How to decide between HashMap and TreeMap?

For inserting, deleting, and locating elements in a Map, the HashMap offers the best alternative. If, however, you need to traverse the keys in a sorted order, then TreeMap is your better alternative. Depending upon the size of your collection, it may be faster to add elements to a HashMap, then convert the map to a TreeMap for sorted key traversal.

10. What is difference between ArrayList and LinkedList?

ArrayList and LinkedList both implement List interface but there are some differences between them.

  1. ArrayList is an index based data structure backed by Array, so it provides random access to it’s elements with performance as O(1) but LinkedList stores data as list of nodes where every node is linked to it’s previous and next node. So even though there is a method to get the element using index, internally it traverse from start to reach at the index node and then return the element, so performance is O(n) that is slower than ArrayList.
  2. Insertion, addition or removal of an element is faster in LinkedList compared to ArrayList because there is no concept of resizing array or updating index when element is added in middle.
  3. LinkedList consumes more memory than ArrayList because every node in LinkedList stores reference of previous and next elements.

11. What are concurrent Collection Classes?

Java 1.5 Concurrent package (java.util.concurrent) contains thread-safe collection classes that allow collections to be modified while iterating. By design Iterator implementation in java.utilpackages are fail-fast and throws ConcurrentModificationException. But Iterator implementation in java.util.concurrent packages are fail-safe and we can modify the collection while iterating. Some of these classes are CopyOnWriteArrayListConcurrentHashMapCopyOnWriteArraySet.

12. What is BlockingQueue?

java.util.concurrent.BlockingQueue is a Queue that supports operations that wait for the queue to become non-empty when retrieving and removing an element, and wait for space to become available in the queue when adding an element.

BlockingQueue interface is part of java collections framework and it’s primarily used for implementing producer consumer problem. We don’t need to worry about waiting for the space to be available for producer or object to be available for consumer in BlockingQueue as it’s handled by implementation classes of BlockingQueue.

Java provides several BlockingQueue implementations such as ArrayBlockingQueue, LinkedBlockingQueue, PriorityBlockingQueue, SynchronousQueue etc.

13. What is Collections Class?

java.util.Collections is a utility class consists exclusively of static methods that operate on or return collections. It contains polymorphic algorithms that operate on collections, “wrappers”, which return a new collection backed by a specified collection, and a few other odds and ends.

This class contains methods for collection framework algorithms, such as binary search, sorting, shuffling, reverse etc.

14. What is Comparable and Comparator interface?

Java provides Comparable interface which should be implemented by any custom class if we want to use Arrays or Collections sorting methods. Comparable interface has compareTo(T obj) method which is used by sorting methods. We should override this method in such a way that it returns a negative integer, zero, or a positive integer if “this” object is less than, equal to, or greater than the object passed as argument.

But, in most real life scenarios, we want sorting based on different parameters. For example, I would like to sort the employees based on Salary as well as age. This is the situation where we need to use Comparator interface  because Comparable.compareTo(Object o) method implementation can sort based on one field only and we can’t chose the field on which we want to sort the Object.

Comparator interface compare(Object o1, Object o2) method need to be implemented that takes two Object argument, it should be implemented in such a way that it returns negative int if first argument is less than the second one and returns zero if they are equal and positive int if first argument is greater than second one.

15. What is difference between Comparable and Comparator interface?

Comparable and Comparator interfaces are used to sort collection or array of objects.

Comparable interface is used to provide the natural sorting of objects and we can use it to provide sorting based on single logic.
Comparator interface is used to provide different algorithms for sorting and we can chose the comparator we want to use to sort the given collection of objects.

16. While passing a Collection as argument to a function, how can we make sure the function will not be able to modify it?

We can create a read-only collection using Collections.unmodifiableCollection(Collection c)method before passing it as argument, this will make sure that any operation to change the collection will throw UnsupportedOperationException.

17. How can we create a synchronized collection from given collection?

We can use Collections.synchronizedCollection(Collection c) to get a synchronized (thread-safe) collection backed by the specified collection.

18. How can we sort a list of Objects?

If we need to sort an array of Objects, we can use Arrays.sort(). If we need to sort a list of objects, we can use Collections.sort(). Both these classes have overloaded sort() methods for natural sorting (using Comparable) or sorting based on criteria (using Comparator).
Collections internally uses Arrays sorting method, so both of them have same performance except that Collections take sometime to convert list to array.

19. Which collection classes are thread-safe?

Vector, Hashtable, Properties and Stack are synchronized classes, so they are thread-safe and can be used in multi-threaded environment. Java 1.5 Concurrent API included some collection classes that allows modification of collection while iteration because they work on the clone of the collection, so they are safe to use in multi-threaded environment.

20. Which collection classes provide random access of it’s elements?

ArrayList, HashMap, TreeMap, Hashtable classes provide random access to it’s elements.

21. How HashMap works in Java?

HashCode and Equals methods in java

We will see hashcode() and equals() methods in java.

These methods can be found in the Object class and hence available to all java classes.Using these two methods, an object can be stored or retrieved from a Hashtable, HashMap or HashSet.

hashcode() and equals() method

hashcode():You might know if you put entry in Map, first hashcode is calculated and this hashcode is used to find index of bucket where this entry will get stored in Map. If you don’t override hashcode method, it will  return integer representation of memory address.

equals():You have to override equals method, when you want to define equality between two object. If you don’t override this method, it will check for reference equality(==) i.e. if tow reference refers to same object or not.

Lets see below example for more details  – 
package com.myjavablog.javainterview.hashcodeandequals;
public class Person {
private String name;
private int age;public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Person class has two attributes name and age.
How can you compare two Person objects? So here you have equals() method from Object class which you can implement in Person class. You can compare two Person objects using particular attribute either name or age from Person class .
Below program will check equality for Person objects –
package com.myjavablog.javainterview.hashcodeandequals;
/**
* @author anupb
*
*/
public class EqualityCheck {/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stubPerson p1 = new Person();
p1.setName("Anup");
Person p2 = new Person();
p2.setName("Anup");System.out.println("Are these two persons same: " + p1.equals(p2));
}}
Output:
Are these two persons same: false
Here you have not implemented equals method in Person class. So above equality check happens on memory address and not on the attributes of the object. Above two objects p1 and p2 points to different memory addresses. Ideally these two Persons are same but above equality check fails.
So now we will add equals() method to Person class which actually compares the objects –

@Override

public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}

Now lets see the output of EqualityCheck –
Are these two persons same: true
This is because you have overridden equals method .
Now lets put these person objects into HashMap – 
Key is Person object
Value – City name to which he belongs (String type)
package com.myjavablog.javainterview.hashcodeandequals;import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;/**
* @author anupb
*
*/
public class HashMapEqualityCheck {/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stubPerson p1 = new Person();
p1.setName("Anup");
Person p2 = new Person();
p2.setName("Anup");

Map<Person, String> personMap = new HashMap<>();
personMap.put(p1, "Pune");
personMap.put(p2, "Pune");

Iterator<Person> itr = personMap.keySet().iterator();

while (itr.hasNext()) {

Person p = itr.next();
String city = personMap.get(p);
System.out.println("Person: " + p.getName() + " City: " + city);
}
}

}

Output:
Person: Anup City: Pune
Person: Anup City: Pune
Now you must be wondering , how HashMap contains two keys with are equal. This is because HashMap first calculates hashcode of the key. It will then calculate the bucket index in the HashMap. If two hashcodes are equal then it will use equals method to compare these two objects and because hashcode for above two person objects uses default hashcode method,Both will have different memory address hence different hashcode.
Now override below hashcode method –
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
Now if you run HashMapEqualityCheck , you can see only one key will be inserted as below –
Person: Anup City: Pune
So now hashcode for above two objects p1 and p2 are same, so Both will be point to same bucket,now equals method will be used to compare them which  will return true.
So the contract says “if you override equals() method then you must override hashCode() method”
hashcode()
  • 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 hash tables.

Key points to remember:

  1. If you are overriding equals method then you should override hashcode() also.
  2. If two objects are equal then they must have same hashcode.
  3. If two objects have same hashcode then they may or may not be equal
  4. Always use same attributes to generate equals and hashcode as in our case we have used name.

2. Java Environment Setup

Java is platform independent i.e. when you write the program and compile it . Then compiler will generate bytecode i.e. .class file .

This bytecode can run on any Java virtual machine (JVM) regardless of computer architecture.

You should know below things before setting the java environment –

  1. JDK(Java Development Kit) : JDK is intended for software developers and includes development tools such as the Java compiler, Javadoc, Jar, and a debugger.
  2. JRE(Java Runtime Environment) : JRE contains the parts of the Java libraries required to run Java programs and is intended for end users. JRE can be view as a subset of JDK.
  3. JVM: JVM (Java Virtual Machine) is an abstract machine. It is a specification that provides runtime environment in which java bytecode can be executed. JVMs are available for many hardware and software platforms.

Steps to install java and setting java path variables – 

  1. Download Java8 JDK is available at Download Java 8.

2. Install java by clicling on .exe file and after that you need to setup java environment variables.

3.  Go to Control Panel -> System and Security -> System -> Environment variables as highlighted below –

4. In java 8 on windows 10 , it creates a symbolic link to java environment automatically under path highlighted below –

So no need to set java path externally .

In windows 7 , you can save the path as below –

Set JAVA_HOME and add this variable in path system variables.

5. You are ready to use java now. Check if java is installed by firing java –version command on command line.

 

1 Introduction to Java

History of Java:
Java programming language was developed by James Ghosling, Patrick Naughton, Mike Sheridan at Sun Microsystems Inc. in 1991.

The initial name was Oak but it was renamed to Java in 1995 as OAK was a registered trademark of another Tech company.

Evolution of Java:

Current stable release of Java is Java SE 8 and development of Java SE 9 is in progress and will be released soon. Below are the versions that have been released –

JDK Alpha and Beta (1995)
JDK 1.0 (23rd Jan, 1996)
JDK 1.1 (19th Feb, 1997)
J2SE 1.2 (8th Dec, 1998)
J2SE 1.3 (8th May, 2000)
J2SE 1.4 (6th Feb, 2002)
J2SE 5.0 (30th Sep, 2004): This version of Java have introduced major changes in java programming world. Some of them are:
Java Concurrency API
Var argument methods
Generics
Annotations
For each loop
Enumerations
Static import
Autoboxing and unboxing etc.
Java SE 6 (11th Dec, 2006)
Java SE 7 (28th July, 2011) : Java 7 has following new major changes:
Multi-catch block
Support of String in Switch case
Try with resources etc.
Java SE 8 (18th March, 2014) : Java 8 has introduced major programming paradigms. Some of them are:
Lambda Expressions.
Functional Interfaces
Default methods in interface.
Streams
Enhanced Security etc

Features of Java:

Java is a general-purpose computer programming language that is concurrent, class-based, object-oriented etc.
Platform independence: Java applications are typically compiled to bytecode that can run on any Java virtual machine (JVM) regardless of computer architecture. Java is write-once, run-anywhere language. Once you compile java code, you can run it on any machine. For example: If you compile your code on Windows OS, you can easily run the same bytecode in linux.

Simple: Java is easy to learn. It does not include concepts of pointers and operator overloading that were available in C++.

Object Oriented: You can model everything into an object which has data and behavior. Java has incorporated various object-oriented concepts such as Abstraction, Encapsulation, Polymorphism, Modularization and inheritance.

Portable: Java byte can be portable to any platform and can be executed on any platform.

Multi-threading: Java has provided multithreading feature which will help you to execute various task in parallel. It has introduced executor framework which is more robust and easy to use.

High performance: Java can not be as fast as C and C++ as it is interpreted language but it has provided various features such as Just in time compiler to increase performance.

I think You might have got some idea about Java now.

Bitnami