List
1.泛型
先看如下代码:
class MyArrayList{
public Object[] elem; // 保存顺序表的元素,即 Object 类型的引用
public int usedSize;
public MyArrayList(Object[] elem) {
this.elem = new Object[10];
}
public void add(Object data){ //尾插
this.elem[this.usedSize++] = data;
}
public Object getPos(int pos){ //获取元素
return this.elem[pos];
}
}
通过使用Object类可以让这个顺序表存储任意类型的变量,但是会有一个问题,就是在使用的时候需要强制类型转换,比如:
MyArrayList myArrayList = new MyArrayList();
myArrayList.add("hello");
String string = (String) myArrayList.getPos(0);
这样如果不强制类型转换的话就会发生运行时异常,所以需要使用泛型。
-
定义:
class MyArrayList<T>
: T只是一个占位符,表示当前类时泛型类
-
意义:
- 1、可以进行类型的自动检查
- 2、自动进行类型转换
-
注意:
- 1、不能够new泛型类型的数组
new T[10]
- 2、简单类型,不能作为泛型类型的参数 <包装类/类>
- 3、泛型类型的参数不参与类型的组成
- 1、不能够new泛型类型的数组
例如:
MyArrayList<String> myArrayList = new MyArrayList<>();
MyArrayList<Integer> myArrayList2 = new MyArrayList<>();
System.out.println(myArrayList);
System.out.println(myArrayList2);
//输出
//collection_test.MyArrayList@4554617c //没有带<String>
//collection_test.MyArrayList@74a14482 //没有带<Integer>
- 使用
class MyArrayList <T> {
public T[] elem;
public int usedSize;
public MyArrayList() {
this.elem = (T[])new Object[10];
}
public void add(T data) {
this.elem[this.usedSize++]=data;
}
public T getPos(int pos) {
return this.elem[pos];
}
}
MyArrayList<String> myArrayList = new MyArrayList<>();
myArrayList.add("hello");
myArrayList.add("world");
String str = myArrayList.getPos(2);
System.out.println(str);
- 泛型是怎么编译的?
- 泛型是在 编译时期 的一个动作,它只存在于编译时期,会执行擦除机制
- 擦除机制:在编译时中T被擦除为Object了
- 一定记住不是替换为Object,而是擦除
- 擦除后只是具备了Object的特性
- 而中的T只是表明在放数据时不能够放出指定类型以外的其它类型的数据,例如,则不能放入除String类型以外的数据
2.包装类
-
1.基本数据类型和包装类直接的对应关系
-
2.使用,
- 装箱(简单类型->包装类类型)和拆箱(包装类类型->简单类型)
int i = 10;
Integer ii = Integer.valueOf(i); // 装箱操作,新建一个 Integer 类型对象,将 i 的值放入对象的某个属性中
Integer ij = new Integer(i);
int j = ii.intValue(); // 拆箱操作,将 Integer 对象中的值取出,放到一个基本数据类型中
int i = 10;
Integer ii = i; // 自动装箱 底层调用的还是valueOf方法
Integer ij = (Integer)i; // 自动装箱
int j = ii; // 自动拆箱
int k = (int)ii; // 自动拆箱
- 注意:如下代码
System.out.println(Integer.valueOf(100) == Integer.valueOf(100));//true
System.out.println(Integer.valueOf(200) == Integer.valueOf(200));//false
第一行代码输出和第二行不同的原因:
查看valueOf方法的源码:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
其中low是-128,high是127。可以发现:
- 当i的取值不在[low,high]这个范围内时,会返回一个新的Integer类的对象
- 而当i的取值在[low,high]这个范围内时,会在同一个缓存区内查找
这便是上述代码执行结果的不同。
3.List常用方法
代码示例:
1.boolean add(E e) 尾插 e
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
2.void add(int index, E element) 将 e 插入到 index 位置
list.add(1,3);
3.boolean addAll(Collection<? extends E> c) 尾插 c 中的元素
List<Integer> list2 = new ArrayList<>();
list2.addAll(list);
4.E remove(int index) 删除 index 位置元素
list.remove(1);
5.boolean remove(Object o) 删除遇到的第一个 o
Integer tmp = list.get(3);
list.remove(tmp);
6.E get(int index) 获取下标 index 位置元素
System.out.println(list.get(0));
7.E set(int index, E element) 将下标 index 位置元素设置为 element
list.set(3,10);
8.boolean contains(Object o) 判断 o 是否在线性表中
System.out.println(list.contains(1));
9.int indexOf(Object o) 返回第一个 o 所在下标
System.out.println(list.indexOf(1));
10.int lastIndexOf(Object o) 返回最后一个 o 的下标
System.out.println(list.lastIndexOf(1));
11.List subList(int fromIndex, int toIndex) 截取部分 list(注意该方法是浅拷贝)
System.out.println(list); //1,2,3,10
List<Integer> ret = list.subList(0,2);
System.out.println(ret); //1,2
ret.set(0,100);
System.out.println(ret); //100,2
System.out.println(list); //100,2,3,10
12.void clear() 清空
list.clear();
List练习题
杨辉三角:给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。
OJ链接:杨辉三角
class Solution {
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> ret = new ArrayList<>();
if(numRows == 0){
return ret;
}
//第一行
List<Integer> one = new ArrayList<>();
one.add(1);
ret.add(one);
for(int i=1;i<numRows;i++){
//当前行
List<Integer> curRow = new ArrayList<>();
curRow.add(1);
//上一行
List<Integer> preRow = ret.get(i-1);
for(int j=1;j<i;j++){
curRow.add(preRow.get(j-1) + preRow.get(j));
}
//该行的最后一个1
curRow.add(1);
ret.add(curRow);
}
return ret;
}
}