Java Interview Questions

author image Hirely
at 05 Jan, 2025

Question: What is the difference between ArrayList and LinkedList in Java?

Answer:

In Java, both ArrayList and LinkedList are classes that implement the List interface, which is part of the Java Collections Framework. However, they have significant differences in terms of their underlying data structures, performance, and typical use cases.


1. Underlying Data Structure:

  • ArrayList:
    • Data Structure: Internally uses a dynamic array (resizable array) to store the elements.
    • Storage: Elements are stored in contiguous memory locations.
  • LinkedList:
    • Data Structure: Internally uses a doubly linked list to store elements. Each element (node) contains a reference to both the previous and the next element.
    • Storage: Each element is stored in separate memory locations, with additional memory used for references to neighboring nodes.

2. Access Time (Random Access):

  • ArrayList:
    • Access Time: O(1) – Direct access to elements via their index is fast, as elements are stored in contiguous memory locations and can be accessed by their index.
  • LinkedList:
    • Access Time: O(n) – Accessing an element in a LinkedList requires traversing the list from the beginning (or end, depending on the position), resulting in slower access times for random access.

3. Insertion and Deletion:

  • ArrayList:
    • Insertion/Deletion Time:
      • At the end: O(1) (amortized) – Adding an element to the end of the list is generally very fast. However, if the array needs to be resized (when it runs out of space), the time complexity can increase to O(n) in those cases.
      • At the middle or beginning: O(n) – When inserting or deleting an element in the middle or beginning, all subsequent elements need to be shifted.
  • LinkedList:
    • Insertion/Deletion Time:
      • At the beginning or end: O(1) – Inserting or deleting at the head or tail of the list is very fast as it only requires updating the references in the linked nodes.
      • At the middle: O(n) – Finding the position where the insertion or deletion should happen still requires O(n) time because of the need to traverse the list.

4. Memory Usage:

  • ArrayList:
    • Memory Usage: Typically uses less memory because it only stores the elements in a dynamic array. The only additional memory overhead is for the resizing of the array when it grows.
  • LinkedList:
    • Memory Usage: Has more memory overhead because each element in the list needs extra memory for storing references (pointers) to the previous and next elements, in addition to the element itself.

5. Performance in Iteration:

  • ArrayList:

    • Iteration: Faster than LinkedList because the elements are stored in contiguous memory locations, and accessing them sequentially is more efficient in terms of cache locality.
  • LinkedList:

    • Iteration: Slower than ArrayList because the elements are not stored in contiguous memory, and traversing the linked nodes involves more pointer dereferencing.

6. Use Cases:

  • ArrayList:
    • Ideal for:
      • Scenarios where fast random access to elements is required.
      • Use cases where elements are mostly added at the end of the list and removed infrequently from the middle or beginning.
  • LinkedList:
    • Ideal for:
      • Scenarios where frequent insertions and deletions from the middle or the ends of the list are needed.
      • Use cases where memory overhead is not a critical concern, and operations like adding/removing from the head or tail need to be efficient.

7. Thread Safety:

  • Both ArrayList and LinkedList are not synchronized by default. If thread safety is required, they must be wrapped in a synchronized wrapper (e.g., Collections.synchronizedList()), or you can use other thread-safe alternatives like CopyOnWriteArrayList.

Summary Table:

FeatureArrayListLinkedList
Underlying Data StructureDynamic Array (Resized Array)Doubly Linked List
Access Time (Random Access)O(1) (Fast index-based access)O(n) (Slow, needs traversal)
Insertion/Deletion (End)O(1) (Amortized)O(1) (Fast at the head/tail)
Insertion/Deletion (Middle/Beginning)O(n) (Requires shifting elements)O(n) (Needs traversal to find position)
Memory UsageLess memory overheadMore memory due to references (pointers)
Iteration SpeedFaster due to contiguous memory layoutSlower due to node traversal
Use CaseEfficient for random access and adding at the endEfficient for frequent insertions and deletions

Conclusion:

  • Use ArrayList when you need fast random access to elements and when insertions and deletions are mostly done at the end of the list.
  • Use LinkedList when you need frequent insertions and deletions at the beginning or middle of the list, and when you don’t need to perform a lot of random access to elements.

Question: How does inheritance work in Java?

Answer:

Inheritance is one of the key features of object-oriented programming (OOP) in Java. It allows a new class (called a subclass or child class) to inherit properties (fields) and behaviors (methods) from an existing class (called a superclass or parent class). This mechanism promotes code reusability and a hierarchical relationship between classes.


Key Concepts of Inheritance in Java:

  1. Superclass (Parent Class):
    The class whose properties and methods are inherited by another class. It can also contain methods that are overridden by the subclass.

  2. Subclass (Child Class):
    The class that inherits from another class. The subclass can extend the functionality of the superclass by adding new methods or overriding existing ones.

  3. extends Keyword:
    In Java, a subclass is created using the extends keyword. This keyword establishes the inheritance relationship between the superclass and subclass.

  4. Method Overriding:
    A subclass can provide its own implementation of a method that is already defined in the superclass. This is known as method overriding and is done using the @Override annotation.

  5. Accessing Parent Class Members:
    The subclass inherits the public and protected members of the superclass but does not inherit the private members. The subclass can access inherited fields and methods directly, except for private members.

  6. Constructor Inheritance:
    Constructors are not inherited by subclasses. However, a subclass can call a constructor of the superclass using the super() keyword, typically to initialize the parent class part of the object.


Syntax of Inheritance in Java:

class Parent {
    // Superclass
    public void display() {
        System.out.println("This is a parent class method.");
    }
}

class Child extends Parent {
    // Subclass
    public void show() {
        System.out.println("This is a child class method.");
    }
}

public class Main {
    public static void main(String[] args) {
        Child child = new Child();
        child.display();  // Inherited method from Parent class
        child.show();     // Method defined in the Child class
    }
}

Key Features of Inheritance:

  1. Single Inheritance:

    • Java supports single inheritance, meaning a subclass can only extend one superclass.
    • However, Java allows a class to implement multiple interfaces, which helps overcome the limitation of single inheritance.
  2. Method Overriding:

    • The subclass can override a method from the superclass to provide its own implementation. The method signature (name, parameters, and return type) in the subclass must match the one in the superclass.
    • Use the @Override annotation to indicate that a method is being overridden.

    Example:

    class Animal {
        public void sound() {
            System.out.println("Animal makes a sound");
        }
    }
    
    class Dog extends Animal {
        @Override
        public void sound() {
            System.out.println("Dog barks");
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            Animal animal = new Animal();
            animal.sound();  // Output: Animal makes a sound
    
            Dog dog = new Dog();
            dog.sound();     // Output: Dog barks
        }
    }
  3. Accessing Superclass Methods:

    • The subclass can access methods and fields of the superclass using the super keyword.
    • super() is used to call the superclass constructor.
    • super.methodName() is used to invoke a method from the superclass.

    Example:

    class Animal {
        public void sound() {
            System.out.println("Animal makes a sound");
        }
    }
    
    class Dog extends Animal {
        public void sound() {
            super.sound();  // Calls the superclass method
            System.out.println("Dog barks");
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            Dog dog = new Dog();
            dog.sound();
            // Output:
            // Animal makes a sound
            // Dog barks
        }
    }
  4. Constructor Chaining:

    • The constructor of a subclass can invoke the constructor of the superclass using super(). If no constructor is explicitly defined in the subclass, the default no-argument constructor of the superclass is called automatically.

    Example:

    class Parent {
        Parent() {
            System.out.println("Parent class constructor");
        }
    }
    
    class Child extends Parent {
        Child() {
            super();  // Calls the Parent class constructor
            System.out.println("Child class constructor");
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            Child child = new Child();
            // Output:
            // Parent class constructor
            // Child class constructor
        }
    }
  5. The super Keyword:

    • Access Superclass Members: super allows access to superclass methods and constructors.
    • Invoke Parent Constructor: super() is used to call the parent class constructor.
  6. Polymorphism:

    • Inheritance enables polymorphism (i.e., the ability of different classes to be treated as instances of the same class through inheritance).
    • Method overriding plays a key role in polymorphism, allowing a subclass to provide a specific implementation for methods defined in the superclass.

Benefits of Inheritance:

  1. Code Reusability: Inheritance promotes code reusability by allowing a subclass to reuse the methods and fields of its superclass.

  2. Extensibility: You can extend the functionality of existing classes by creating subclasses without modifying the original class.

  3. Method Overriding: Allows subclasses to customize or extend the behavior of the superclass methods, providing more flexibility.


Types of Inheritance in Java:

  1. Single Inheritance:
    A class can inherit from only one superclass. Java supports single inheritance.

  2. Multilevel Inheritance:
    A class can inherit from another subclass, creating a chain of inheritance.

    class A {
        void methodA() {
            System.out.println("Class A");
        }
    }
    
    class B extends A {
        void methodB() {
            System.out.println("Class B");
        }
    }
    
    class C extends B {
        void methodC() {
            System.out.println("Class C");
        }
    }
  3. Hierarchical Inheritance:
    A single superclass can have multiple subclasses.

    class A {
        void methodA() {
            System.out.println("Class A");
        }
    }
    
    class B extends A {
        void methodB() {
            System.out.println("Class B");
        }
    }
    
    class C extends A {
        void methodC() {
            System.out.println("Class C");
        }
    }
  4. Multiple Inheritance (Through Interfaces):
    Java does not support multiple inheritance (where a class inherits from multiple classes) directly. However, a class can implement multiple interfaces.


Summary:

  • Inheritance in Java allows a subclass to inherit properties and methods from a superclass, enabling code reuse and a hierarchical class structure.
  • The extends keyword is used to create the subclass.
  • The subclass can override methods, access superclass members using the super keyword, and call superclass constructors using super().
  • Inheritance also supports polymorphism, making it a fundamental feature of object-oriented programming in Java.

Read More

If you can’t get enough from this article, Aihirely has plenty more related information, such as Java interview questions, Java interview experiences, and details about various Java job positions. Click here to check it out.

Related Posts

Trace Job opportunities

Hirely, your exclusive interview companion, empowers your competence and facilitates your interviews.

Get Started Now