简述
Java的ArrayList类有点类似Python的List,看源码可以发现其底层是使用一个数组保存元素,在数组长度不够长的时候自动扩容,从而达到近无限容量(是有上限的)保存元素的目的。其初始化时默认的容量是10。
构造方法
- 直接空参构造,构造出来的ArrayList默认容量为10.
import java.utils.ArrayList
ArrayList<Byte> arr = new ArrayList<>();
- 构造时传入容量
import java.utils.ArrayList
ArrayList<Byte> arr = new ArrayList<>(20);
- 构造时传入一个Collection对象
import java.utils.ArrayList
ArrayList<Integer> arr = new ArrayList<>();
arr.add(1);
arr.add(2);
arr.add(3);
arr.add(4);
ArrayList<Integer> arr1 = new ArrayList<>(arr);
System.out.println(arr1); // [1, 2, 3, 4]
主要方法
- 添加元素
ArrayList<Integer> arr = new ArrayList<>();
arr.add(2); // 添加一个元素
arr.add(3);
arr.add(4);
arr.add(0, 10); // 在指定索引位置添加1个元素,后面的元素向右移动1个位置
System.out.println(arr); // [10, 2, 3, 4]
- 删除元素
ArrayList<String> arr = new ArrayList<>();
arr.add("a");
arr.add("b");
arr.add("c");
arr.remove(2); // 删除指定索引处的元素,后续的元素左移 [a,b,a]
arr.remove("a"); // 删除第一个匹配的元素 [b,a]
- 获取某个索引的元素
ArrayList<String> arr = new ArrayList<>();
arr.add("a");
arr.add("b");
arr.add("c");
arr.get(0); // 获取0索引的元素
- 获取子列表
ArrayList<String> arr = new ArrayList<>();
arr.add("a");
arr.add("b");
arr.add("c");
arr.add("a");
List<String> strings = arr.subList(1, 3); // 获取子列表
System.out.println(strings); // [b, c]
strings.set(0, "abcd"); // 改变子列表0索引的值
System.out.println(strings); // [abcd, c]
System.out.println(arr); //此处注意,sublist并为重新创建一个List对象,是直接在父ArrayList上操作,所以修改子列表也会修改父ArrayList [a, abcd, c, a]
- 对有所元素进行修改,类似于Pthon的map
ArrayList<Student1 > arr1= new ArrayList<>();
Student1 s1 = new Student1("张三", 30);
Student1 s2 = new Student1("李四", 40);
Student1 s3 = new Student1("王五", 50);
arr1.add(s1);
arr1.add(s2);
arr1.add(s3);
arr1.forEach(x -> x.setScore(x.getScore() + 10));
for (Student1 student1 : arr1) {
System.out.println(student1.getScore()); // 40, 50, 60
}
- 其他方法不常用,要用再看源码
注意点
ArrayList类虽然类似Python的List,但是也有不同之处。python的List对象内可以存储不同类型的元素,ArrayList对象不行,其必须存储初始化时定义的元素类型或其子类。(这个理解是错误的,ArrayList是可以存储不同类型的数据的,只是Java不建议这样操作)
ArrayList arr = new ArrayList(); // 不定义存储的数据类型,就可以存储不同的数据类型
arr.add(1);
arr.add('a');
arr.add("abc");
for (int i = 0; i < arr.size(); i++) {
System.out.println(arr.get(i));
} // 1 a abc
- ArrayList对象只能存储引用型数据类型,对于基础数据类型(int, byte等),必须使用其包装类才能存储
ArrayList<int> arr1= new ArrayList<>(); // 报错
ArrayList<Integer> arr1= new ArrayList<>(); // 使用int的包装类Integer
- 调用ArrayList.forEach方法时,如果ArrayList内存储的是不可修改的数据类型,那对元素的操作无法生效。
ArrayList<String > arr = new ArrayList<>();
arr.add("a");
arr.add("b");
arr.add("c");
arr.add("d");
arr.forEach(x -> {x = x + "f";}); // 该操作无效果
System.out.println(arr); // [a,b,c,d]
- 调用ArrayList.subList方法时,并不是真正创建了一个新的List对象,只是将在子List上的操作映射到原有的ArrayList上进行操作。如果对子List进行修改,那么原有的ArrayList也会变动。
ArrayList<String> arr = new ArrayList<>();
arr.add("a");
arr.add("b");
arr.add("c");
arr.add("a");
List<String> strings = arr.subList(1, 3); // 获取子列表
System.out.println(strings); // [b, c]
strings.set(0, "abcd"); // 改变子列表0索引的值
System.out.println(strings); // [abcd, c]
System.out.println(arr); //此处注意,sublist并为重新创建一个List对象,是直接在父ArrayList上操作,所以修改子列表也会修改父ArrayList [a, abcd, c, a]