Java Collection Framework interview questions

The Java Engineer
By -
0

1. How does HashMap work internally in Java?

Answer: HashMap in Java uses an array of nodes (buckets) to store key-value pairs. Each bucket is a linked list or a red-black tree if the list grows too long (threshold is 8). The key's hashCode is used to determine the bucket index. If multiple keys map to the same bucket (collision), they are stored in a linked list or tree at that index. When retrieving a value, the hashCode and equals method are used to find the exact key-value pair.

Example:

Map<String, Integer> map = new HashMap<>();
map.put("one", 1);
map.put("two", 2);
System.out.println(map.get("one")); // Output: 1

2. What are the differences between ArrayList and LinkedList?

Answer:

  • Underlying Data Structure: ArrayList uses a dynamic array, while LinkedList uses a doubly linked list.
  • Access Time: ArrayList provides constant-time access for get and set operations (O(1)), while LinkedList provides linear-time access (O(n)).
  • Insertion/Deletion: LinkedList is better for frequent insertions and deletions (O(1) for add/remove) in the middle of the list, whereas ArrayList requires shifting elements (O(n)).
  • Memory Overhead: LinkedList uses more memory due to storing references to the previous and next elements.

Example:

List<String> arrayList = new ArrayList<>();
List<String> linkedList = new LinkedList<>();

3. Explain the difference between HashSet and TreeSet.

Answer:

  • Ordering: HashSet does not maintain any order of elements, while TreeSet maintains elements in a sorted (natural ordering or specified comparator) order.
  • Performance: HashSet offers constant time (O(1)) performance for basic operations like add, remove, and contains. TreeSet offers log-time (O(log n)) performance.
  • Implementation: HashSet is backed by a HashMap, while TreeSet is backed by a TreeMap.

Example:

Set<String> hashSet = new HashSet<>();
Set<String> treeSet = new TreeSet<>();
hashSet.add("b");
hashSet.add("a");
treeSet.add("b");
treeSet.add("a");
System.out.println(hashSet); // Output might be [a, b] or [b, a]
System.out.println(treeSet); // Output: [a, b]

4. How does ConcurrentHashMap achieve thread safety?

Answer: ConcurrentHashMap achieves thread safety through a combination of lock striping and concurrent techniques. It divides the map into segments (by default 16), each with its own lock. This reduces contention by allowing multiple threads to operate on different segments concurrently. For finer-grained locking, it uses a non-blocking algorithm with volatile variables and CAS (Compare-And-Swap) operations.

Example:

Map<String, Integer> concurrentMap = new ConcurrentHashMap<>();
concurrentMap.put("one", 1);
concurrentMap.put("two", 2);
System.out.println(concurrentMap.get("one")); // Output: 1

5. What are weak references and how are they used in WeakHashMap?

Answer: Weak references allow objects to be collected by the garbage collector if they are not strongly reachable. WeakHashMap uses weak references for its keys, meaning that if a key is no longer referenced elsewhere, it can be garbage collected, and the corresponding entry will be removed from the map.

Example:

Map<String, String> weakHashMap = new WeakHashMap<>();
String key = new String("key");
String value = "value";
weakHashMap.put(key, value);

System.out.println(weakHashMap); // Output: {key=value}
key = null; // Making key eligible for garbage collection
System.gc(); // Suggesting JVM to run GC
System.out.println(weakHashMap); // Output might be {} after GC

6. What is the difference between synchronizedList and CopyOnWriteArrayList?

Answer:

  • synchronizedList: Returns a synchronized (thread-safe) list backed by the specified list. All operations on the returned list are synchronized. Performance can degrade due to the cost of synchronization.
    List<String> list = Collections.synchronizedList(new ArrayList<>());
    
  • CopyOnWriteArrayList: Creates a new copy of the list for each write operation (add, set, etc.). It is best suited for scenarios where read operations are more frequent than write operations, as read operations do not require locking.
    List<String> list = new CopyOnWriteArrayList<>();
    

7. How does PriorityQueue work in Java?

Answer: PriorityQueue is a queue data structure that orders elements according to their natural ordering or by a comparator provided at queue construction time. It uses a binary heap to store elements. The head of the queue is the least element with respect to the specified ordering.

Example:

PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.add(10);
pq.add(20);
pq.add(15);
System.out.println(pq.peek()); // Output: 10
System.out.println(pq.poll()); // Output: 10
System.out.println(pq.poll()); // Output: 15

8. What are the differences between Iterator and ListIterator?

Answer:

  • Iterator: Can iterate over a collection in one direction (forward) and can remove elements during iteration.
  • ListIterator: Extends Iterator and adds functionalities such as bidirectional traversal (forward and backward), and ability to modify elements during iteration.

Example:

List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
ListIterator<String> listIterator = list.listIterator();

while (listIterator.hasNext()) {
    System.out.println(listIterator.next()); // Forward iteration
}
while (listIterator.hasPrevious()) {
    System.out.println(listIterator.previous()); // Backward iteration
}

9. How does EnumSet work in Java?

Answer: EnumSet is a specialized Set implementation for use with enum types. It is highly efficient because it internally uses bit vectors, making it extremely fast for operations like add, remove, and contains. EnumSet is ordered by the natural order of the enum values.

Example:

enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }

EnumSet<Day> weekend = EnumSet.of(Day.SATURDAY, Day.SUNDAY);
System.out.println(weekend); // Output: [SATURDAY, SUNDAY]

10. What is the difference between Comparable and Comparator?

Answer:

  • Comparable: Used to define the natural ordering of objects. The class itself must implement the Comparable interface and override the compareTo method.

    class Person implements Comparable<Person> {
        String name;
        int age;
    
        @Override
        public int compareTo(Person other) {
            return this.age - other.age;
        }
    }
    
  • Comparator: Used to define an external comparison logic. It can be used to compare objects in a custom order. Implemented in a separate class or as an anonymous class.
    class NameComparator implements Comparator<Person> {
        @Override
        public int compare(Person p1, Person p2) {
            return p1.name.compareTo(p2.name);
        }
    }
    


queue interface: deque, double ended queue

Map:

hashmap: non-synchronized, 1 null

hahs table: synchonized, non null

sorted map: tree map, acending

fail fast: concurrent modification exception

fail safe: no exception: they work on clone of colelction , later on they merge it on.

blocking queue: producer consumer use case

no overflow, no underflow

synchronized , concurrent

both thread safe, faster and efficient hashmap

hash map : no other thread can read segments

lock stripping: seg 1 is lock other thread worker as seg 2, 3,4




collection hierarchy

list: order, duplicate, index based

queue: fifo

set: sorted, no duplicate

hashset: hashtable, unique, one null, order

linked hashset: orderd

sorted set: comparatble interface asceneding

treeset: self binary serach tree[red black tree]

map: key-value, unique, duplicate value

Post a Comment

0Comments

Post a Comment (0)

#buttons=(Ok, Go it!) #days=(20)

Our website uses cookies to enhance your experience. Learn more
Ok, Go it!