泛型详细知识请看 泛型
具体信息请查看 API 帮助文档
ArrayList
- 集合:提供一种存储空间可变的存储模型,存储的数据容量可以发生改变
- ArrayList
集合的特点: 长度可以变化,只能存储引用数据类型。
1. 集合特点
ArrayList
的特点如下:
-
可变长度:
ArrayList
的长度可以根据需要动态增长或缩减。 -
泛型支持:
ArrayList
可以存储任何类型的对象,包括基本数据类型的包装类。 -
有序集合:
ArrayList
中的元素按照它们被添加的顺序进行排序。 -
可随机访问:
ArrayList
使用索引来访问和操作其中的元素,可以通过索引快速访问任意位置的元素。
2. 方法
2.1 构造方法
方法名 | 说明 |
---|---|
public ArrayList() | 创建一个空的集合对象 |
ArrayList(int initialCapacity) | 创建指定初始容量的 ArrayList |
ArrayList(Collection<? extends E> c) | 创建包含指定集合中的元素的 ArrayList。 |
2.2 成员方法
方法名 | 说明 |
---|---|
public boolean add(要添加的元素) | 将指定的元素追加到此集合的末尾 |
public boolean remove(要删除的元素) | 删除指定元素,返回值表示是否删除成功 |
public E remove(int index) | 删除指定索引处的元素,返回被删除的元素 |
public E set(int index,E element) | 修改指定索引处的元素,返回被修改的元素 |
public E get(int index) | 返回指定索引处的元素 |
public int size() | 返回集合中的元素的个数 |
3. 方法操作
下面是一些常用的 ArrayList 操作:
-
创建 ArrayList 对象
可以使用
ArrayList<E> list = new ArrayList<>()
或List<E> list = new ArrayList<>()
来创建一个 ArrayList 对象,其中E
是要存储的元素类型。例如:
ArrayList<String> list = new ArrayList<String>(); List<Integer> numbers = new ArrayList<>();
-
添加元素
可以使用
add(E element)
方法将元素添加到 ArrayList 的末尾。例如:
list.add("Apple"); list.add("Banana"); list.add("Orange"); numbers.add(1); numbers.add(2); numbers.add(3);
-
获取元素
使用
get(int index)
方法可以获取指定索引位置的元素。例如:
String fruit = list.get(0); // fruit 等于 "Apple" int number = numbers.get(1); // number 等于 2
-
更新元素
使用
set(int index, E element)
方法可以更新指定索引位置的元素。例如:
list.set(1, "Grapes"); // 将索引为1的元素更新为 "Grapes" numbers.set(0, 5); // 将索引为0的元素更新为 5
-
删除元素
使用
remove(int index)
方法可以删除指定索引位置的元素,使用remove(Object element)
方法可以删除指定元素。例如;
list.remove(2); // 删除索引为2的元素 "Orange" numbers.remove(Integer.valueOf(2)); // 删除值为2的元素
-
判断是否包含元素
使用
contains(Object element)
方法可以判断 ArrayList 是否包含指定元素。例如:
boolean containsFruit = list.contains("Apple"); // containsFruit 等于 true boolean containsNumber = numbers.contains(4); // containsNumber 等于 false
-
获取 ArrayList 的大小
使用
size()
方法可以获取 ArrayList 中的元素数量。例如:
int sizeOfList = list.size(); // sizeOfList 等于 2 int sizeOfNumbers = numbers.size(); // sizeOfNumbers 等于 2
-
遍历元素
可以使用循环结构(如
for
或foreach
)来遍历 ArrayList 中的所有元素。例如;
// 使用 for 循环遍历 ArrayList for (String fruit : list) { System.out.println(fruit); } // 使用 forEach 遍历 ArrayList list.forEach(fruit -> System.out.println(fruit));
4. 泛型
详细知识请看 泛型
泛型(Generics)是 Java 5 中引入的一个新特性,它提供了编译时类型检查和更好的代码复用的能力,使得代码更加健壮和安全。
泛型是参数化类型的一种实现方式,可以将类型参数化来达到适应多种类型的需求。
当我们声明一个泛型类或方法时,可以使用一个或多个类型参数(type parameter)来表示该类或方法中要使用的数据类型,这个数据类型可以是任意一种有效的 Java 类型(包括基本类型和对象类型)。
例如,下面是一个简单的泛型类的示例:
public class Box<T> {
private T content;
public Box(T content) {
this.content = content;
}
public T getContent() {
return this.content;
}
public void setContent(T content) {
this.content = content;
}
}
这里,我们使用了一个类型参数
T
来表示这个类中的某个数据类型,这个类型可以是任意一种有效的 Java 类型。
在实例化这个类时,我们需要提供一个具体的数据类型作为实参(这个实参必须是一个类型,即 <T>
不是指具体值)。
例如:
Box<String> box = new Box<String>("Hello World");
String content = box.getContent();
在这个示例中,我们使用
Box<String>
来实例化泛型类Box
,这个类型实参告诉编译器,我们使用Box
中的类型参数T
为String
类型,因此Box
类中的content
属性和getContent()
、setContent()
方法的返回值和参数类型都是String
类型。
5. 源码分析
核心步骤:
-
创建ArrayList对象的时候,他在底层先创建了一个长度为0的数组。
数组名字:elementDate,定义变量size。
size这个变量有两层含义:
①:元素的个数,也就是集合的长度
②:下一个元素的存入位置 -
添加元素,添加第一个元素时,底层会创建一个新的长度为10的数组,添加完毕后,size++
扩容时机一:
- 当存满时候,会创建一个新的数组,新数组的长度,是原来的1.5倍,也就是长度为15.再把所有的元素,全拷贝到新数组中。如果继续添加数据,这个长度为15的数组也满了,那么下次还会继续扩容,还是1.5倍。
扩容时机二:
-
一次性添加多个数据,扩容1.5倍不够,怎么办呀?
如果一次添加多个元素,1.5倍放不下,那么新创建数组的长度以实际为准。
举个例子:在一开始,如果默认的长度为10的数组已经装满了,在装满的情况下,我一次性要添加100个数据很显然,10扩容1.5倍,变成15,还是不够,怎么办?
此时新数组的长度,就以实际情况为准,就是110
添加一个元素时的扩容:
添加多个元素时的扩容: