Core Java Interview Questions and Answers (2025)

author image Hirely
at 05 Jan, 2025

Question: How to sort an ArrayList in Java?

Answer:

In Java, you can sort an ArrayList using several methods, primarily through the Collections utility class or using the Stream API (for Java 8 and later). Here’s how you can sort an ArrayList:


1. Using Collections.sort():

The most common way to sort an ArrayList is by using the sort() method from the Collections class. This method works by sorting the elements in natural order (for comparable elements like Integer, String, etc.) or using a custom comparator if you want a specific order.

Example:

Sorting an ArrayList of integers (Natural Order):

import java.util.ArrayList;
import java.util.Collections;

public class Main {
    public static void main(String[] args) {
        // Create an ArrayList
        ArrayList<Integer> list = new ArrayList<>();
        list.add(5);
        list.add(2);
        list.add(8);
        list.add(1);

        // Print original list
        System.out.println("Original List: " + list);

        // Sort the list in ascending order
        Collections.sort(list);

        // Print sorted list
        System.out.println("Sorted List: " + list);
    }
}

Output:

Original List: [5, 2, 8, 1]
Sorted List: [1, 2, 5, 8]

Sorting an ArrayList of Strings (Natural Order):

import java.util.ArrayList;
import java.util.Collections;

public class Main {
    public static void main(String[] args) {
        // Create an ArrayList
        ArrayList<String> list = new ArrayList<>();
        list.add("Banana");
        list.add("Apple");
        list.add("Cherry");
        list.add("Mango");

        // Print original list
        System.out.println("Original List: " + list);

        // Sort the list in ascending order (alphabetically)
        Collections.sort(list);

        // Print sorted list
        System.out.println("Sorted List: " + list);
    }
}

Output:

Original List: [Banana, Apple, Cherry, Mango]
Sorted List: [Apple, Banana, Cherry, Mango]

2. Sorting in Reverse Order:

You can sort an ArrayList in descending order using the Collections.sort() method along with a custom Comparator.

Example:

import java.util.ArrayList;
import java.util.Collections;

public class Main {
    public static void main(String[] args) {
        // Create an ArrayList
        ArrayList<Integer> list = new ArrayList<>();
        list.add(5);
        list.add(2);
        list.add(8);
        list.add(1);

        // Print original list
        System.out.println("Original List: " + list);

        // Sort the list in descending order
        Collections.sort(list, Collections.reverseOrder());

        // Print sorted list
        System.out.println("Sorted List (Descending): " + list);
    }
}

Output:

Original List: [5, 2, 8, 1]
Sorted List (Descending): [8, 5, 2, 1]

3. Using a Custom Comparator:

You can use a custom Comparator to define a custom sorting order (e.g., sorting based on specific criteria).

Example (Sorting a list of Person objects by age):

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

class Person {
    String name;
    int age;

    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return name + ": " + age;
    }
}

public class Main {
    public static void main(String[] args) {
        // Create an ArrayList of Person objects
        ArrayList<Person> people = new ArrayList<>();
        people.add(new Person("Alice", 30));
        people.add(new Person("Bob", 25));
        people.add(new Person("Charlie", 35));

        // Print original list
        System.out.println("Original List: " + people);

        // Sort the list by age using a custom comparator
        Collections.sort(people, new Comparator<Person>() {
            @Override
            public int compare(Person p1, Person p2) {
                return Integer.compare(p1.age, p2.age); // Sort by age in ascending order
            }
        });

        // Print sorted list
        System.out.println("Sorted List (By Age): " + people);
    }
}

Output:

Original List: [Alice: 30, Bob: 25, Charlie: 35]
Sorted List (By Age): [Bob: 25, Alice: 30, Charlie: 35]

4. Using Java 8 Streams (Custom Sorting):

With Java 8 and later, you can use the Stream API to sort an ArrayList more concisely, especially when you want to apply custom sorting logic.

Example (Sorting using Java 8 Stream API):

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) {
        // Create an ArrayList
        ArrayList<Integer> list = new ArrayList<>();
        list.add(5);
        list.add(2);
        list.add(8);
        list.add(1);

        // Print original list
        System.out.println("Original List: " + list);

        // Sort the list using Java 8 Streams
        List<Integer> sortedList = list.stream()
                                      .sorted() // Sorts in natural order (ascending)
                                      .collect(Collectors.toList());

        // Print sorted list
        System.out.println("Sorted List (Using Streams): " + sortedList);
    }
}

Output:

Original List: [5, 2, 8, 1]
Sorted List (Using Streams): [1, 2, 5, 8]

You can also sort in reverse order or apply custom sorting logic using Comparator:

List<Integer> sortedList = list.stream()
                               .sorted((a, b) -> b - a) // Sort in reverse order
                               .collect(Collectors.toList());

5. Using List.sort() Method (Java 8 and later):

From Java 8 onwards, the List interface itself has a sort() method, which provides a convenient way to sort an ArrayList directly.

Example:

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

public class Main {
    public static void main(String[] args) {
        // Create an ArrayList
        List<Integer> list = new ArrayList<>();
        list.add(5);
        list.add(2);
        list.add(8);
        list.add(1);

        // Print original list
        System.out.println("Original List: " + list);

        // Sort the list in ascending order
        list.sort(null); // Using natural order (ascending)

        // Print sorted list
        System.out.println("Sorted List: " + list);
    }
}

Output:

Original List: [5, 2, 8, 1]
Sorted List: [1, 2, 5, 8]

Conclusion:

  • Collections.sort(): Used for sorting lists in natural order or with a custom comparator.
  • List.sort(): A method available from Java 8 onward that sorts the list directly, using either natural order or a comparator.
  • Stream API: A functional approach for sorting that can be useful for chaining operations.
  • Custom Comparator: Allows sorting based on specific criteria when the natural order is not sufficient.

These methods provide a flexible way to sort ArrayList elements in different orders based on your needs.

Question: What are the differences between String, StringBuilder, and StringBuffer in Java?

Answer:

In Java, String, StringBuilder, and StringBuffer are all used to handle text, but they have significant differences in terms of performance, mutability, and thread-safety. Here is a breakdown of their differences:


1. String:

Definition:
A String in Java is an immutable sequence of characters. Once a String object is created, its value cannot be changed.

Key Points:

  • Immutability: String objects are immutable. When you modify a String, a new String object is created, and the original object remains unchanged.
  • Memory Usage: Because of immutability, frequent string modifications can cause excessive memory consumption, as new String objects are created each time a modification is made.
  • Performance: String manipulation (such as concatenation) using String is inefficient, especially inside loops, because it creates new String objects with every modification.
  • Thread Safety: Since String objects are immutable, they are inherently thread-safe.

Example:

String str = "Hello";
str = str + " World"; // A new String object is created here

2. StringBuilder:

Definition:
StringBuilder is a mutable sequence of characters. It allows modification of strings without creating new objects each time, making it more efficient for concatenation or modifications.

Key Points:

  • Mutability: StringBuilder objects are mutable, meaning their contents can be modified after they are created.
  • Performance: It is more efficient than String for concatenation or modifications inside loops because it does not create new objects every time a change is made. Instead, it modifies the internal character array.
  • Thread Safety: StringBuilder is not thread-safe. If multiple threads access a StringBuilder concurrently, it must be synchronized externally to avoid issues.
  • Use Case: It is typically used when you know the string will be modified frequently, and thread safety is not a concern.

Example:

StringBuilder sb = new StringBuilder("Hello");
sb.append(" World");  // The StringBuilder object is modified in place
System.out.println(sb); // Output: Hello World

3. StringBuffer:

Definition:
StringBuffer is similar to StringBuilder but is thread-safe. It provides mutable strings and is designed for situations where thread safety is required.

Key Points:

  • Mutability: Like StringBuilder, StringBuffer objects are mutable. You can modify their contents without creating new objects.
  • Performance: It is generally slower than StringBuilder because it is synchronized for thread safety. The synchronization comes with a performance overhead.
  • Thread Safety: StringBuffer is thread-safe because its methods are synchronized, which means that only one thread can modify the StringBuffer object at a time.
  • Use Case: It is useful when multiple threads need to modify the same string concurrently.

Example:

StringBuffer sbf = new StringBuffer("Hello");
sbf.append(" World");  // The StringBuffer object is modified in place
System.out.println(sbf); // Output: Hello World

Key Differences:

FeatureStringStringBuilderStringBuffer
ImmutabilityImmutableMutableMutable
Thread SafetyThread-safe (due to immutability)Not thread-safeThread-safe (methods are synchronized)
PerformanceSlow for repeated modificationsFast for repeated modificationsSlower than StringBuilder due to synchronization
Use CaseWhen you don’t modify the string frequentlyWhen you modify strings frequently and don’t need thread safetyWhen you modify strings in a multi-threaded environment
Memory UsageHigher memory consumption due to immutabilityMore efficient (less memory usage)Similar to StringBuilder, but with a slight overhead due to synchronization
ExampleString str = "Hello"; str = str + " World";StringBuilder sb = new StringBuilder("Hello"); sb.append(" World");StringBuffer sbf = new StringBuffer("Hello"); sbf.append(" World");

Conclusion:

  • String: Use when you need an immutable sequence of characters and don’t expect frequent modifications.
  • StringBuilder: Use when you need a mutable sequence of characters and performance is critical, and thread safety is not a concern.
  • StringBuffer: Use when you need a mutable sequence of characters and thread safety is required.

In most cases, StringBuilder is preferred for performance reasons, especially in single-threaded applications, while StringBuffer should be used when working with multiple threads.

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