Core Java Interview Questions and Answers (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 aString
, a newString
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 newString
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 aStringBuilder
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 theStringBuffer
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:
Feature | String | StringBuilder | StringBuffer |
---|---|---|---|
Immutability | Immutable | Mutable | Mutable |
Thread Safety | Thread-safe (due to immutability) | Not thread-safe | Thread-safe (methods are synchronized) |
Performance | Slow for repeated modifications | Fast for repeated modifications | Slower than StringBuilder due to synchronization |
Use Case | When you don’t modify the string frequently | When you modify strings frequently and don’t need thread safety | When you modify strings in a multi-threaded environment |
Memory Usage | Higher memory consumption due to immutability | More efficient (less memory usage) | Similar to StringBuilder , but with a slight overhead due to synchronization |
Example | String 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.
Tags
- Java
- Java interview questions
- ArrayList vs LinkedList
- Inheritance in Java
- Method overloading
- Method overriding
- String vs StringBuilder vs StringBuffer
- Multithreading in Java
- Thread creation in Java
- Final keyword in Java
- JSON parsing in Java
- Random number generation in Java
- Comparing strings in Java
- String reversal in Java
- Calculation using switch case
- Remove duplicates in ArrayList
- Exception handling in Java
- Two dimensional array in Java
- Interface vs abstract class in Java
- Java programming basics
- Java collections
- Java performance optimization
- Java data structures