文章目录
ArrayList
- ArrayList底层是一段连续的空间,并且可以动态扩容,是一个动态类型的顺序表
- 在任意位置插入或删除元素时,需要将该位置后序元素整体往前或者往后搬
移,故时间复杂度为O(N) - 扩容需要申请新空间,拷贝数据,释放旧空间,同时存不满会产生资源浪费
一、 ArrayList的使用
1. ArrayList的构造方法
1.1源码分析
无参构造的时候,并没有对它底层的elementData数组分配内存
而是在第一次调用add方法的时候,对底层的elementData数组分配内存且大小为10;
ArrayList的扩容是1.5倍进行的
有参构造时,传的参数直接在构造的时候对数组进行内存分配
传的参数类型是E或者E的子类,并且一定实现了Collection接口
public static void main(String[] args) {
LinkedList<Integer> list = new LinkedList<>();
list.add(4);
list.add(3);
list.add(2);
ArrayList<Number> arrayList = new ArrayList<>(list);//实例化对象,调用构造方法
arrayList.add(1);
System.out.println(arrayList);
}
[4, 3, 2, 1]
2.ArrayList的方法
2.1 add方法
2.2 remove方法
arrayList.remove(3);//删除索引的元素
arrayList.remove(new Integer(4));//删除指定的Integer类型的元素
通过new一个指定的类型,进行装箱,来进行删除
2.3 subList 方法
List<Number> subList = arrayList.subList(0, 2);
System.out.println(subList);
System.out.println("-------------");
//[4, 3, 5, 2, 1]
//[4, 3]
subList.set(0,99);
System.out.println(subList);
System.out.println(arrayList);
//[99, 3]
//[99, 3, 5, 2, 1]
1.左闭右开
2.两者公用同一个elementData数组,修改截取的内容,原内容也会改变
二、ArrayList的遍历
1. for循环
for (int i = 0; i < arrayList.size(); i++) {
System.out.print(arrayList.get(i)+" ");//99 3 5 2 1
}
2. foreach
for (Number x:arrayList) {
System.out.print(x+" ");
}
3. 迭代器
ListIterator<Number> it = arrayList.listIterator();//迭代器
while (it.hasNext()){
System.out.print(it.next()+" ");
}
1.先判断it有没有下一个数
2.如果有,it向下走,并打印,没有:循环结束
三、 ArrayList的应用
1.CVTE面试题
S1 = “welcome to cvte”;
S2 = “come”;
要求在S1中删除在S2中出现过的字符
ArrayLIst写法
public static void main(String[] args) {
String s1 = "welcome to cvte";
String s2 = "come";
//wltvt
ArrayList<Character> arrayList1 = new ArrayList<>();
for (int i = 0; i < s1.length(); i++) {
char c = s1.charAt(i);
if (!s2.contains((c + ""))) { //c+"" 变成一个字符串
arrayList1.add(c);
}
}
System.out.println(arrayList1);
for(int i = 0;i<arrayList1.size();i++){
System.out.print(arrayList1.get(i));
}
}
1.先遍历字符串s1,拿到每个字符
2.在s2中进行比较,如果没有,存进arrayList
3.打印arrayList
StringBuilder写法
public static void main(String[] args) {
String s1 = "welcome to cvte";
String s2 = "come";
//wltvt
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < s1.length(); i++) {
char c = s1.charAt(i);
if (s2.indexOf(c)==-1){
stringBuilder.append(c);
}
}
String res = stringBuilder.toString();
System.out.println(res);
}
2.杨辉三角
上图可以转化为:
思路
1.List的嵌套,看成二维数组来解决问题
2.左右两侧都是1
中间的元素,等于该列上一行的元素,加上前一列前一行的元素
方法
1.先将1存进第一行
2.将第一行数组存进顺序表中
3.在循环中,创建当前行的数组,并拿到前一行的数组
- 这里注意,因为已经存了一个数组,所以外层循环是i从1开始,numRows前结束
4.同样先在当前行数组存一个1
- 这里的内循环,同理 j从1开始,直到i之前,因为i的值等于当前行元素个数
5.取的前一行的当前列与前一行的前一列的元素之和,存进当前行
6.在当前行最后存一个1
5.将当前行,存进顺序表中
class Solution {
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> ret = new ArrayList<>();
List<Integer> row = new ArrayList<>();
row.add(1);//把1存进row数组
ret.add(row);//把row数组存进ret数组
for (int i = 1; i < numRows; i++) {
List<Integer> curRow = new ArrayList<>();
List<Integer> pervRow = ret.get(i - 1);//基于当前i的前一行
curRow.add(1);//开头的1
for (int j = 1; j < i; j++) {//开头是1,j从1 开始,i的值恰好为最后一个数的下标,j小于i
int x = pervRow.get(j) + pervRow.get(j - 1);//前一行的当前列加上前一行的前一列
curRow.add(x);//存进当前行
}
curRow.add(1);//最后的1
ret.add(curRow);
}
return ret;
}
}