Question
Given that a Set can be created with HashSet, how do you create a List in Java?
For example:
Set mySet = new HashSet();
What is the equivalent way to declare and instantiate a List?
Short Answer
You will learn that List is a Java interface and is usually created using a concrete implementation such as ArrayList or LinkedList. You will also learn why generic types such as List<String> are important and how to choose an appropriate list implementation.
Concept
A List is an ordered collection in Java. Unlike a Set, a list:
- Keeps elements in insertion order.
- Allows duplicate values.
- Lets you access elements by their numeric position, called an index.
For example, a list can store the values "red", "blue", and "red" again. The first item has index 0, the second has index 1, and so on.
List belongs to the Java Collections Framework and is an interface. An interface describes available operations, but it cannot create objects itself. Therefore, you declare a variable using List and instantiate a class that implements it.
The most common implementation is ArrayList:
List<String> names = new ArrayList<>();
This approach is preferred because your code depends on the general List contract rather than a specific implementation. You can later change ArrayList to LinkedList with minimal changes if your needs change.
Mental Model
Think of a List as a numbered shelf.
- Each shelf position has a number:
0,1,2, and so on. - You can put the same item on more than one shelf position.
- Items stay in the order in which you place them.
List is the label describing what the shelf system can do: add, remove, find, and retrieve items by position. ArrayList is one particular kind of shelf system that provides those operations.
In the same way, List<String> describes what you need, while new ArrayList<>() specifies how it is built.
Syntax and Examples
Import the List interface and an implementation such as ArrayList:
import java.util.ArrayList;
import java.util.List;
Create a list with a generic element type:
List<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Apple");
System.out.println(fruits); // [Apple, Banana, Apple]
System.out.println(fruits.get(0)); // Apple
List<String> means this list may contain only String values. The diamond operator, <>, lets Java infer the same type on the right side.
You can also create a list with initial values:
List<Integer> scores = new ArrayList<>(List.of(10, 20, 30));
scores.add(40);
System.out.println(scores); // [10, 20, 30, 40]
new ArrayList<>(List.of(...)) creates a mutable containing the supplied values.
Step by Step Execution
Consider this program:
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> tasks = new ArrayList<>();
tasks.add("Email customer");
tasks.add("Write report");
tasks.add("Deploy application");
String firstTask = tasks.get(0);
tasks.remove("Write report");
System.out.println(firstTask);
System.out.println(tasks);
}
}
Execution steps:
List<String> tasksdeclares a variable that can refer to a list of strings.new ArrayList<>()creates an empty, mutable list.- The first
addplaces"Email customer"at index0. - The second and third
addcalls place items at indices1and2.
Real World Use Cases
Lists are useful whenever order matters or duplicate values are valid.
- Shopping carts: Store products in the order a customer adds them.
- API responses: Return an ordered collection of search results, messages, or invoices.
- Form validation: Keep a list of validation error messages to show a user.
- Task queues: Maintain a sequence of jobs that must be processed.
- CSV and file processing: Read lines or records into a collection while preserving file order.
- User interface data: Store rows for a table, notifications, menu items, or chat messages.
For example, an API service might collect validation errors:
List<String> errors = new ArrayList<>();
if (email == null || email.isBlank()) {
errors.add("Email is required.");
}
if (password == null || password.length() < 8) {
errors.add("Password must contain at least 8 characters.");
}
Real Codebase Usage
In production code, developers usually program to the List interface and choose an implementation based on normal usage.
private final List<String> auditEvents = new ArrayList<>();
Common patterns include:
- Use
List<T>in variable declarations, parameters, and return types. This keeps code flexible.
public List<String> findUsernames() {
return new ArrayList<>();
}
-
Use
ArrayListby default. It is usually a good choice for appending items and reading by index. -
Validate before adding data. Guard clauses prevent invalid values from entering a list.
public void addTag(List<String> tags, String tag) {
if (tag == null || tag.isBlank()) {
return;
}
tags.add(tag.trim());
}
Common Mistakes
Using raw types
This compiles, but it removes type safety:
List items = new ArrayList();
items.add("text");
items.add(42);
Avoid raw types. Specify the element type:
List<String> items = new ArrayList<>();
items.add("text");
Trying to instantiate List directly
This does not work because List is an interface:
List<String> names = new List<>(); // Does not compile
Create an implementing class instead:
List<String> names = new ArrayList<>();
Forgetting that indices start at zero
List<String> names = List.of("Ana", "Bo");
System.out.println(names.get(2));
Comparisons
| Collection or implementation | Ordering | Duplicates | Typical use |
|---|---|---|---|
List | Preserves insertion order | Allowed | Ordered sequences, items accessed by index |
Set | Depends on implementation | Not allowed | Unique values, such as tags or IDs |
ArrayList | Preserves insertion order | Allowed | Default list choice; fast indexed reads and appending |
LinkedList | Preserves insertion order | Allowed | Occasional use when repeatedly adding/removing at list ends |
ArrayList vs LinkedList
Cheat Sheet
import java.util.ArrayList;
import java.util.List;
// Empty mutable list
List<String> names = new ArrayList<>();
// Mutable list with initial items
List<String> names = new ArrayList<>(List.of("Ana", "Bo"));
// Fixed, unmodifiable list
List<String> names = List.of("Ana", "Bo");
| Task | Code |
|---|---|
| Add an item | names.add("Cy"); |
| Read by index | names.get(0); |
| Replace by index | names.set(0, "Ada"); |
| Remove by index | names.remove(0); |
| Remove by value | names.remove("Ada"); |
FAQ
How do I create an empty List in Java?
Use ArrayList:
List<String> items = new ArrayList<>();
Import java.util.List and java.util.ArrayList.
Why use List<String> instead of just List?
List<String> restricts the list to strings and lets the compiler catch incorrect additions. A raw List can hold mixed types and requires unsafe casts.
Can a Java List contain duplicate elements?
Yes. A list preserves order and allows duplicates. This is a key difference from a Set.
Can I write new List<>() in Java?
No. List is an interface, not a class. Use an implementation such as new ArrayList<>().
Which List implementation should I use in Java?
Use ArrayList by default. Consider another implementation only when you have a specific need and understand its trade-offs.
Mini Project
Description
Build a small shopping-list manager for a command-line application. The program demonstrates creating a mutable List, adding entries, reading items by index, removing an entry, and safely handling an empty list.
Goal
Create and update an ordered shopping list using List<String> and ArrayList.
Requirements
Use List<String> with an ArrayList implementation.|Add at least three shopping items in a defined order.|Display each item with its zero-based index.|Remove one item by its value.|Print the first remaining item only when the list is not empty.
Keep learning
Related questions
Add External JAR Files to an IntelliJ IDEA Java Project
Learn how to add external JAR dependencies to an IntelliJ IDEA Java project using module libraries, and when to use Maven or Gradle instead.
Avoiding Java Code in JSP with JSP 2: EL and JSTL Explained
Learn how to avoid Java scriptlets in JSP 2 using Expression Language and JSTL, with examples, best practices, and common mistakes.
Call a Method After a Delay in Android Java
Learn how to run Java code after a delay in Android using Handler.postDelayed, manage the main thread, and cancel callbacks safely.