java中一种允许多种数据类型的特性。
//此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
//在实例化泛型类时,必须指定T的具体类型
public class Generic<T>{
//key这个成员变量的类型为T,T的类型由外部指定
private T key;
public Generic(T key) { //泛型构造方法形参key的类型也为T,T的类型由外部指定
this.key = key;
}
public T getKey(){ //泛型方法getKey的返回值类型为T,T的类型由外部指定
return key;
}
}
//泛型的类型参数只能是类类型(包括自定义类),不能是简单类型
//传入的实参类型需与泛型的类型参数类型相同,即为Integer.
Generic<Integer> genericInteger = new Generic<Integer>(123456);
//传入的实参类型需与泛型的类型参数类型相同,即为String.
Generic<String> genericString = new Generic<String>("key_vlaue");
Log.d("泛型测试","key is " + genericInteger.getKey());
Log.d("泛型测试","key is " + genericString.getKey());
12-27 09:20:04.432 13063-13063/? D/泛型测试: key is 123456
12-27 09:20:04.432 13063-13063/? D/泛型测试: key is key_vlaue
int是简单数据类型,Integer是一种“class”
只要两个变量的值是向等的,则结果为true
Integer i = new Integer(100);
int j = 100;
System.out.print(i == j); //true
因为包装类Integer和基本数据类型int比较时,java会自动拆包装为int,然后进行比较,实际上就变为两个int变量的比较
Integer i = new Integer(100);
Integer j = 100;
System.out.print(i == j); //false
非new生成的Integer变量指向的是java常量池中的对象,而new Integer()生成的变量指向堆中新建的对象,两者在内存中的地址不同
我个人理解是,为了满足一些特定开发需求,因为基本数据类型不能满足面向对象编程所有的开发需求。
并且使用泛型定义时也不能用int,要用Integer:
List<int> list = new ArrayList<int>(); //不可以
List<Integer> list = new ArrayList<Integer>(); //可以
List arrayList = new ArrayList();
List arrayList = new ArrayList();
Array的容量固定且无法动态改变。可以将ArrayList想象成一种“会自动扩增容量的Array”。
Array基于index,List继承Collection,是集合的一种
List有两个重要的实现类:ArrayList和LinkedList
| ArrayList | LinkedList | |
|---|---|---|
| 基于什么 | 数组 | 双链表 |
| get/set | 有index,复杂度是O(1) | 代价较大 |
| 插入数据 | 数组装满的时候要将所有的数据重新装入一个新的数组,最坏情况为O(n) | 复杂度O(1) |
| 删除数据 | 代价较大 | 复杂度O(1) |
| 长度 | 不定义长度时,默认生成长度为10的ArrayList,如果数据大于这个值,则会增大list长度。 | |
| 存储空间 | 占用空间较少,每个节点是实际的数据 | 占用空间较多,每个节点存储的是实际的数据和前后节点的位置 |
| 什么情况下用 | 访问数据多 | 更多的插入和删除元素 |