每日一言
People who neglect to make efforts or who don’t take any actions at all are always the ones who dream that someday they will suddenly become wildly successful. — Misaki Nakahara from Welcome to the N.H.K.
列表(Lists)
ArrayList
ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它没有固定大小的限制,我们可以添加或删除元素。
ArrayList 实现了List接口。
- 优点:高效的随机访问和快速的尾部插入
- 缺点:中间插入和删除相对较慢
创建ArrayList
ArrayList类位于java.util 包中。使用前需要引入:
import java.util.ArrayList;
ArrayList<E> objectName = new ArrayList<>();
- E : 泛型数据类型,用于设置objectName 的数据类型,只能为引用数据类型。
简单回顾:
Java数据类型
在 Java 中,数据类型分为两大类:
- 基本数据类型 (Primitive Types) :这些是 Java 语言内置的类型,直接存储数据值。它们包括
int,byte,short,long,float,double,boolean,char。 - 引用数据类型 (Reference Types) :这些类型存储的是对象的 引用 (内存地址),而不是对象本身。这包括所有的类(如
String,Integer,ArrayList, 以及你自己创建的类)、接口、数组等。
所以当我们想要创建基本类型的ArrayList时,我们应该使用它们对应的包装类(Wrapper Class).
int->Integerdouble->Doubleboolean->Booleanchar->Character
// 正确:使用包装类 Integer
ArrayList<Integer> numbers = new ArrayList<>();
// 错误:不能使用基本类型 int
// ArrayList<int> numbers = new ArrayList<>();
操作ArrayList
ArrayList 时一个数组队列,提供了相关的添加、删除、修改、遍历等功能。
添加元素
ArratList 使用add()方法添加元素。
import java.util.ArrayList;
public class RunoobTest {
public static void main(String[] args) {
ArrayList<String> sites = new ArrayList<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Weibo");
System.out.println(sites);
}
}
注:打印一个类的时候,会自动调用该类的toString方法。
所以上述代码打印结果与下面的代码一致:
System.out.println(sites.toString());
打印结果为:
[Google, Runoob, Taobao, Weibo]
访问元素
访问ArrayList 中的元素使用get()
import java.util.ArrayList;
public class RunoobTest {
public static void main(String[] args) {
ArrayList<String> sites = new ArrayList<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Weibo");
System.out.println(sites.get(1)); // 访问第二个元素
}
}
输出:
Runoob
修改元素
修改ArrayList中的元素使用,使用set()方法,set(int index, E element)方法,index表示要替换的元素的位置,第二个元素是新元素(element),表示要新设的值:
import java.util.ArrayList;
public class RunoobTest {
public static void main(String[] args) {
ArrayList<String> sites = new ArrayList<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Weibo");
sites.set(2, "Wiki"); // 第一个参数为索引位置,第二个为要修改的值
System.out.println(sites);
}
}
结果:
[Google, Runoob, Wiki, Weibo]
删除元素
删除ArrayList中的元素可以使用remove()方法:
import java.util.ArrayList;
public class RunoobTest {
public static void main(String[] args) {
ArrayList<String> sites = new ArrayList<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Weibo");
sites.remove(0); // 删除第四个元素
System.out.println(sites);
}
}
删除元素后,后面的元素会向前补齐。输出结果:
[Runoob, Taobao, Weibo]
计算大小
可以通过size() 方法获取ArrayList的大小:
sites.size();
引用列表
java中的基本类型对应的引用类:
| 基本类型 | 引用类型 |
|---|---|
| boolean | Boolean |
| byte | Byte |
| short | Short |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
| char | Character |
列表的排序
Arrays只能对于各种类的数组进行排序,不能传入ArrayList参数。所以对于列表的排序我们使用Collections类。
import java.util.ArrayList;
import java.math.BigInteger;
import java.util.Collections;
public class RunoobTest {
public static void main(String[] args) {
ArrayList<BigInteger> sites = new ArrayList<>();
sites.add(new BigInteger("1231231231321321332312"));
sites.add(new BigInteger("2"));
sites.add(new BigInteger("3"));
sites.add(new BigInteger("4"));
Collections.sort(sites);
System.out.println("ArrayList: " + sites);
}
}
Java ArrayList方法
Java ArrayList 常用方法列表如下:
| 方法 | 描述 |
|---|---|
| add() | 将元素插入到指定位置的 arraylist 中 |
| addAll() | 添加集合中的所有元素到 arraylist 中 |
| clear() | 删除 arraylist 中的所有元素 |
| clone() | 复制一份 arraylist |
| contains() | 判断元素是否在 arraylist |
| get() | 通过索引值获取 arraylist 中的元素 |
| indexOf() | 返回 arraylist 中元素的索引值 |
| removeAll() | 删除存在于指定集合中的 arraylist 里的所有元素 |
| remove() | 删除 arraylist 里的单个元素 |
| size() | 返回 arraylist 里元素数量 |
| isEmpty() | 判断 arraylist 是否为空 |
| subList() | 截取部分 arraylist 的元素 |
| set() | 替换 arraylist 中指定索引的元素 |
| sort() | 对 arraylist 元素进行排序 |
| toArray() | 将 arraylist 转换为数组 |
| toString() | 将 arraylist 转换为字符串 |
| ensureCapacity() | 设置指定容量大小的 arraylist |
| lastIndexOf() | 返回指定元素在 arraylist 中最后一次出现的位置 |
| retainAll() | 保留 arraylist 中在指定集合中也存在的那些元素 |
| containsAll() | 查看 arraylist 是否包含指定集合中的所有元素 |
| trimToSize() | 将 arraylist 中的容量调整为数组中的元素个数 |
| removeRange() | 删除 arraylist 中指定索引之间存在的元素 |
| replaceAll() | 将给定的操作内容替换掉数组中每一个元素 |
| removeIf() | 删除所有满足特定条件的 arraylist 元素 |
| forEach() | 遍历 arraylist 中每一个元素并执行特定操作 |
Java LinkedList(链表)
一下情况使用链表:
- 需要通过循环迭代的方式来访问列表中的某些元素
- 需要频繁的列表开头,中间,末尾等位置进行添加和删除操作
LinkedList 继承自:AbstractSequentialList类。同时实现了以下接口:
- Queue(普通的队列)
- List(列表)
- Deuqe(双端队列,可用作栈)
- Cloneable(可以克隆)
- Serializable(可支持序列化)
使用LinkedList
引入:
// 引入 LinkedList 类
import java.util.LinkedList;
普通创建方法:
LinkedList<E> list = new LinkedList<E>(); // 普通创建方法
使用集合创建:
LinkedList<E> list = new LinkedList<E>(Collection<? extends E> c)
这个构造函数会创建一个新的 LinkedList,并将参数 c 中所有元素按照它们在 c 中的迭代顺序添加到这个新的 LinkedList 中。
LinkedList的三种用法
链表(List接口)
对于链表,我们可以直接使用add方法进行添加,add方法继承自List接口。
// 引入 LinkedList 类
import java.util.LinkedList;
public class RunoobTest {
public static void main(String[] args) {
LinkedList<String> sites = new LinkedList<String>();
sites.add("Google");
sites.add("Runoob"); //添加到末尾
sites.add(1,"Taobao"); //添加到指定位置
sites.add(0,"Weibo"); //添加到开头
System.out.println(sites);
}
}
移除元素使用remove():
// 引入 LinkedList 类
import java.util.LinkedList;
public class RunoobTest {
public static void main(String[] args) {
LinkedList<String> sites = new LinkedList<String>();
sites.add("Google");
sites.add("Runoob"); //添加到末尾
sites.add(1,"Taobao"); //添加到指定位置
sites.add(0,"Weibo"); //添加到开头
//移除元素
sites.remove("Google"); //移除指定元素
sites.remove(1); //移除指定位置的元素
sites.clear(); //清空列表
System.out.println(sites);
}
}
作为Queue使用
它实现了 Queue 接口(通过实现 Deque 接口间接实现)。
import java.util.LinkedList;
import java.util.Queue;
public class LinkedListAsQueue {
public static void main(String[] args) {
// 1. 声明为 Queue 类型,用 LinkedList 实例化
Queue<String> taskQueue = new LinkedList<>();
// 2. 使用 offer() 向队尾添加元素 (入队)
System.out.println("Offering 'Task 1': " + taskQueue.offer("Task 1"));
System.out.println("Offering 'Task 2': " + taskQueue.offer("Task 2"));
taskQueue.offer("Task 3");
System.out.println("Current queue: " + taskQueue); // Output: Current queue: [Task 1, Task 2, Task 3]
// 3. 使用 peek() 查看队首元素 (不移除)
String nextTask = taskQueue.peek();
System.out.println("Next task (peek): " + nextTask); // Output: Next task (peek): Task 1
System.out.println("Queue after peek: " + taskQueue); // Output: Queue after peek: [Task 1, Task 2, Task 3]
// 4. 使用 poll() 从队首移除并返回元素 (出队)
String completedTask = taskQueue.poll();
System.out.println("Completed task (poll): " + completedTask); // Output: Completed task (poll): Task 1
System.out.println("Queue after poll: " + taskQueue); // Output: Queue after poll: [Task 2, Task 3]
// 继续出队
System.out.println("Polling next: " + taskQueue.poll()); // Output: Polling next: Task 2
System.out.println("Polling next: " + taskQueue.poll()); // Output: Polling next: Task 3
// 队列为空时 poll() 返回 null
System.out.println("Polling from empty queue: " + taskQueue.poll()); // Output: Polling from empty queue: null
// 队列为空时 peek() 返回 null
System.out.println("Peeking into empty queue: " + taskQueue.peek()); // Output: Peeking into empty queue: null
// 注意:如果使用 remove() 或 element() 操作空队列会抛出 NoSuchElementException
// taskQueue.remove(); // Throws NoSuchElementException
// taskQueue.element(); // Throws NoSuchElementException
}
}
作为栈使用
它实现了 Deque 接口,而 Deque 接口本身就提供了栈操作所需的方法。
import java.util.LinkedList;
import java.util.Deque; // Deque 接口提供了栈方法
public class LinkedListAsStack {
public static void main(String[] args) {
// 可以直接用 LinkedList,或者用 Deque 声明以强调其栈用途
Deque<String> browserHistory = new LinkedList<>();
// LinkedList<String> browserHistory = new LinkedList<>(); // 这样也可以
// 1. 使用 push() 将元素压入栈顶
browserHistory.push("google.com");
browserHistory.push("github.com");
browserHistory.push("stackoverflow.com");
System.out.println("Current stack (top first): " + browserHistory);
// Output: Current stack (top first): [stackoverflow.com, github.com, google.com]
// 2. 使用 peek() 查看栈顶元素 (不移除)
String currentPage = browserHistory.peek();
System.out.println("Current page (peek): " + currentPage); // Output: Current page (peek): stackoverflow.com
System.out.println("Stack after peek: " + browserHistory);
// Output: Stack after peek: [stackoverflow.com, github.com, google.com]
// 3. 使用 pop() 从栈顶弹出元素 (移除并返回)
String previousPage = browserHistory.pop();
System.out.println("Went back to (pop): " + previousPage); // Output: Went back to (pop): stackoverflow.com
System.out.println("Stack after pop: " + browserHistory);
// Output: Stack after pop: [github.com, google.com]
// 继续弹出
System.out.println("Popping next: " + browserHistory.pop()); // Output: Popping next: github.com
System.out.println("Popping next: " + browserHistory.pop()); // Output: Popping next: google.com
// 栈为空时 peek() 返回 null
System.out.println("Peeking into empty stack: " + browserHistory.peek()); // Output: Peeking into empty stack: null
// 栈为空时 pop() 抛出 NoSuchElementException
try {
browserHistory.pop();
} catch (java.util.NoSuchElementException e) {
System.out.println("Caught exception when popping from empty stack: " + e);
// Output: Caught exception when popping from empty stack: java.util.NoSuchElementException
}
}
}
其他方法
| 方法 | 描述 |
|---|---|
| public boolean add(E e) | 链表末尾添加元素,返回是否成功,成功为 true,失败为 false。 |
| public void add(int index, E element) | 向指定位置插入元素。 |
| public boolean addAll(Collection c) | 将一个集合的所有元素添加到链表后面,返回是否成功,成功为 true,失败为 false。 |
| public boolean addAll(int index, Collection c) | 将一个集合的所有元素添加到链表的指定位置后面,返回是否成功,成功为 true,失败为 false。 |
| public void addFirst(E e) | 元素添加到头部。 |
| public void addLast(E e) | 元素添加到尾部。 |
| public boolean offer(E e) | 向链表末尾添加元素,返回是否成功,成功为 true,失败为 false。 |
| public boolean offerFirst(E e) | 头部插入元素,返回是否成功,成功为 true,失败为 false。 |
| public boolean offerLast(E e) | 尾部插入元素,返回是否成功,成功为 true,失败为 false。 |
| public void clear() | 清空链表。 |
| public E removeFirst() | 删除并返回第一个元素。 |
| public E removeLast() | 删除并返回最后一个元素。 |
| public boolean remove(Object o) | 删除某一元素,返回是否成功,成功为 true,失败为 false。 |
| public E remove(int index) | 删除指定位置的元素。 |
| public E poll() | 删除并返回第一个元素。 |
| public E remove() | 删除并返回第一个元素。 |
| public boolean contains(Object o) | 判断是否含有某一元素。 |
| public E get(int index) | 返回指定位置的元素。 |
| public E getFirst() | 返回第一个元素。 |
| public E getLast() | 返回最后一个元素。 |
| public int indexOf(Object o) | 查找指定元素从前往后第一次出现的索引。 |
| public int lastIndexOf(Object o) | 查找指定元素最后一次出现的索引。 |
| public E peek() | 返回第一个元素。 |
| public E element() | 返回第一个元素。 |
| public E peekFirst() | 返回头部元素。 |
| public E peekLast() | 返回尾部元素。 |
| public E set(int index, E element) | 设置指定位置的元素。 |
| public Object clone() | 克隆该列表。 |
| public Iterator descendingIterator() | 返回倒序迭代器。 |
| public int size() | 返回链表元素个数。 |
| public ListIterator listIterator(int index) | 返回从指定位置开始到末尾的迭代器。 |
| public Object[] toArray() | 返回一个由链表元素组成的数组。 |
| public T[] toArray(T[] a) | 返回一个由链表元素转换类型而成的数组。 |