Java is a powerful programming language with a rich set of data structures and collection classes, one of which is List
the list. List
It is an important interface in the Java collection framework, which allows us to store a set of elements in an ordered and repeatable manner. List
This blog will go from basic to advanced, introducing interfaces and common List
implementation classes in Java in detail to help beginners deeply understand the concept, usage and application scenarios of lists.
What is a List?
In Java, List
is an interface, which inherits from Collection
interface. List
The interface represents an ordered sequence of elements, allowing duplication of elements. This means that you can store a set of elements in the order they were added, and allow the same element to appear multiple times. List
The interface provides many methods to operate elements in the list, including adding, deleting, getting, searching, etc.
Basic methods of List interface
Let's first understand List
some basic methods in the interface:
-
Adding elements : You can
add()
add elements to the end of the list using the method. For example:List<String> fruits = new ArrayList<>(); fruits.add("苹果"); fruits.add("香蕉"); fruits.add("橙子");
-
Get elements : Use
get()
the method to get elements in the list based on index. Indexes start counting from 0, indicating the first element. For example:String firstFruit = fruits.get(0); // 获取第一个元素(苹果)
-
Remove elements : Use
remove()
the method to remove elements from a list based on index or element value. For example:fruits.remove(1); // 删除索引为 1 的元素(香蕉) fruits.remove("橙子"); // 删除值为 "橙子" 的元素
-
Get the list size : Use
size()
the method to get the number of elements in the list. For example:int size = fruits.size(); // 获取列表大小,此时 size 为 2
-
Traversing a list : You can use a loop or an iterator to iterate over the elements in a list. For example:
for (String fruit : fruits) { System.out.println(fruit); }
Common implementation classes of List
Java provides multiple classes that implement List
interfaces, each with its own characteristics and uses. Here are some common List
implementation classes:
-
ArrayList :
ArrayList
is a dynamic array based on array implementation, which supports fast random access to elements. If you need to insert and delete elements frequently, you can choose another implementation. -
LinkedList :
LinkedList
It is a list based on a doubly linked list. It is suitable for situations where frequent insertion and deletion operations are required. Its insertion and deletion operations areArrayList
faster than . -
Vector :
Vector
SimilarArrayList
, but thread-safe. Consider using lists if you are using them in a multi-threaded environmentVector
. -
Stack :
Stack
It is a class inherited fromVector
and represents the stack data structure, supporting push and pop operations.
ArrayList vs. LinkedList
ArrayList
and LinkedList
are two common list implementations, they have different characteristics and applicable scenarios:
-
ArrayList is suitable for situations where frequent random access to elements is required. Since it is implemented on an array, any element in the list can be accessed quickly. However, insertion and deletion operations may be
LinkedList
slower than . -
LinkedList is suitable for situations where frequent insertion and deletion operations are required. Since it is implemented based on a linked list, insertion and deletion operations are usually
ArrayList
faster than . However, random access to elements can be slower because the linked list needs to be traversed to find the element.
Below we will delve into the differences and applicable scenarios of these two list implementations.
ArrayList
-
Advantages :
- Fast random access: Being based on arrays,
ArrayList
it supports fast access to elements by index. This makes read operations very efficient.
- Fast random access: Being based on arrays,
-
Applicable scenarios :
ArrayList
A better choice when frequent read operations (accessing elements through indexes) are required .ArrayList
It works better when the size of the list is relatively stable or fixed .
-
Example :
List<String> arrayList = new ArrayList<>(); arrayList.add("苹果"); arrayList.add("香蕉"); arrayList.add("橙子"); String fruit = arrayList.get(1); // 快速访问第二个元素
LinkedList
-
Advantages :
- Fast insertion and deletion: Because it is based on a linked list,
LinkedList
it supports fast insertion and deletion of elements at any position. This makes editing operations very efficient.
- Fast insertion and deletion: Because it is based on a linked list,
-
Applicable scenarios :
LinkedList
It is a better choice when frequent insertion and deletion operations are required .- It works better when the size of the list may change dynamically
LinkedList
.
-
Example :
List<String> linkedList = new LinkedList<>(); linkedList.add("苹果"); linkedList.add("香蕉"); linkedList.add("橙子"); linkedList.add(1, "葡萄"); // 在第二个位置插入元素 linkedList.remove(0); // 移除第一个元素
Traverse List
Iterating List
over the elements in is a common operation. You can use different methods to implement traversal, here are a few common ones:
1. Use for-each loop
Use the enhanced for-each loop to conveniently iterate over List
the elements in :
List<String> fruits = new ArrayList<>();
fruits.add("苹果");
fruits.add("香蕉");
fruits.add("橙子");
for (String fruit : fruits) {
System.out.println(fruit);
}
2. Use the classic for loop
You can use a traditional for loop to iterate by index List
:
for (int i = 0; i < fruits.size(); i++) {
String fruit = fruits.get(i);
System.out.println(fruit);
}
3. Use iterators
Iterators are a more general way of traversing and are applicable to all List
implementations. Here is an example of traversing using an iterator:
Iterator<String> iterator = fruits.iterator();
while (iterator.hasNext()) {
String fruit = iterator.next();
System.out.println(fruit);
}
Other common operations on List
In addition to basic add, delete, get and traverse operations, it List
also supports many other common operations, such as determining whether the list is empty, finding elements, reversing the list, etc. Here are some commonly used methods:
-
Determine whether the list is empty :
boolean isEmpty = fruits.isEmpty(); // 返回 true,如果列表为空
-
Find the index of an element :
int index = fruits.indexOf("香蕉"); // 返回元素 "香蕉" 的索引,如果不存在则返回 -1
-
Reverse the list :
Collections.reverse(fruits); // 反转列表中的元素顺序
-
Get sublist :
List<String> subList = fruits.subList(1, 3); // 获取索引 1 到 2 之间的子列表
-
Replace elements :
fruits.set(0, "葡萄"); // 将第一个元素替换为 "葡萄"
These methods can help you manipulate elements in the list more flexibly.
Notes on using List
When using in Java List
, there are some considerations and best practices to ensure that your code is efficient, readable, and free of potential problems. Here are some List
usage notes:
-
Choose the appropriate
List
implementation class : Choose the appropriate implementation class based on your needsList
. If you need frequent random access to elements, chooseArrayList
; if you need frequent insertion and deletion operations, chooseLinkedList
. -
Use generics : Always declare using generics
List
to ensure type safety. For example,List<String>
represent a list that can only store strings. -
Avoid modifying the list in a loop : When using
for-each
a loop to iterate over a list, do not modify the contents of the list in the loop, which may cause unpredictable behavior. If modification is needed, use an iterator.// 不推荐的做法,可能会导致 ConcurrentModificationException for (String fruit : fruits) { if (fruit.equals("橙子")) { fruits.remove(fruit); } } // 推荐的做法,使用迭代器 Iterator<String> iterator = fruits.iterator(); while (iterator.hasNext()) { String fruit = iterator.next(); if (fruit.equals("橙子")) { iterator.remove(); } }
-
Note on null values :
List
Null values are allowed to be stored, but they must be handled with care to avoid throwing a Null Pointer Exception in subsequent operations. -
Consider concurrency : If your list needs to be used in a multi-threaded environment, consider using a thread-safe
List
implementation class such asVector
orCollections.synchronizedList()
wrapping your list with . -
Performance optimization : If you need to insert and delete a large number of elements frequently, consider using it
LinkedList
, it has better performance in this regard. And for a large number of read operations,ArrayList
it is more efficient. -
Avoid unnecessary boxing and unboxing : When using basic data types (such as
int
), avoid boxing them into wrapper classes (such asInteger
) to reduce memory consumption and performance penalties. -
Set the capacity appropriately : If you know the approximate size of the list, you can
ArrayList
specify the initial capacity when creating it to reduce subsequent dynamic expansion.List<String> fruits = new ArrayList<>(100); // 指定初始容量为 100
-
Use
Collections.unmodifiableList()
protected lists : If you need to pass a list to other code, but don't want it to be modified, you can use toCollections.unmodifiableList()
create an unmodifiable list.List<String> readOnlyList = Collections.unmodifiableList(fruits);
-
Documentation and comments : Add documentation comments to your code that describe the purpose, characteristics, and expected behavior of the list so that other developers can use it correctly.
Following these considerations will help you manage and use it better List
, thereby improving the quality and maintainability of your code. Remember, understanding the basics and best practices of lists is important for writing efficient Java code.
Summarize
Java's List
interface is a powerful tool for working with ordered, repeatable collections of elements. Different List
implementations are suitable for different scenarios, and you can choose the appropriate implementation class according to your needs. Understanding List
the basic methods, traversal methods, and common operations of the interface will help you better use lists to solve problems. With practice and practice, you will become proficient in using lists and gradually gain a deeper understanding of more advanced operations and best practices. I hope this blog can help you master List
the basic knowledge in Java and become more comfortable in programming.