子接口:List(有序不唯一)
List因为是有序集合,所以还多了一种遍历方式,以ArrayList为例:
for(int i=0;i<al.size();i++){
System.out.println(al.get(i)); 此处取出的依然
} 是Object类型
ArrayList(实现了List接口)
底层采用了数组的数据结构,特点是有序不唯一。
初始存储空间是10,但会自动扩容,但存储空间到达一半时进行扩容,扩大1.5倍即先乘以3再除以2最后加1。
ArrayList al = new ArrayList();
al.add(5);
al.add(7);
al.add(3);
al.add(0);
System.out.println(al.size());打印al元素个数
System.out.println(al.get(0));ArrayList集合可以通过下标索引获取对应元素,因为是有序集合。
ArrayList虽然底层采用的是数组,但是工作机制上有很大区别,数组一旦定义以后是无法在本身的内存空间内修改个数的,如果要修改数组的个数只能另外开辟一个新的内存空间,而原来的内存空间由于没有引用指向则会被gc回收,这样就造成了不断地创建空间和回收空间降低了程序执行的效率。而ArrayList的扩容机制决定了其执行效率的高效。但是ArrayList当删除其中某一个数值时,后面的数据会紧跟着接上,所以这时集合的元素个数变了,而删除元素后面的元素所对应的下标也相应的变了。如下例:
ArrayList al = new ArrayList();
al.add(1);
al.add(2);
al.add(3);
al.add(4);
al.add(5);
System.out.println(al.size());
for(int i = 0;i<al.size();i++){
al.remove(i);删除下标索引所对应的数据
}
System.out.println(al.size());
打印结果是:2
在循环执行时,执行第一次删除第一个元素后,后面的元素接着补上,现在的size()是4,但是下标索引只能取到3,这时i=1,删除第二个元素,但这时的第二个元素是这个新集合的第二个元素,相当于原来集合的第三个元素,这样就会留下一个元素,依次执行最后剩余两个元素。
Collections.sort(result);对List集合进行排序的方法
Collections.reverse(result);将集合颠倒反转
LinkedList
底层数据结构采用链表,用法与ArrayList基本相同。但是其存储机制和ArrayList不同,底层是首尾相连的存储区间,每个区间尾部存储着下一个头部的内存地址,但是查询遍历很不方便,当要找某一个元素都要从链表头开始查找,但是在添加和删除空间的时候并不用为整个链表开辟新的内存空间,而是删除那一块,就删掉那一块,删除块前面的空间和后面的空间相连即可。添加空间类似。
所以如果只是大量查询遍历数据时,还是使用ArrayList,但如果经常增删数据还是使用LinkedList。
Vector
ArrayList Vector进行比较
①Vector是线程安全的 当中所有方法都是synchronized修饰的同步方法
ArrayList 线程不安全的 非同步的
所谓同步就是同一时间只能有一个线程访问文件,而非同步就是同一时间可以有多个线程访问文件
非同步的一定比同步的效率高
②ArrayList扩容 *3/2+1
Vector扩容 *2+1
对应ArrayList和Vector有StringBuilder和StringBuffer,StringBuffer同样有自动扩容的特性,而String却不具备,所以字符串拼接速度由低到高是:String,StringBuffer,StringBuilder
StringBuffer buff = new StringBuffer();
for(int i = 0;i<1000000;i++){
buff.append(i);
}
StringBuffer和StringBuilder追加字符串的方法都是append(…)
相比于HashSet,List更优先考虑equals()方法,List会首先调用equals()方法比较新来元素和已有元素,如下例:
public class TestList{
public static void main(String[] args){
Student stu = new Student("Tom",30);
Student stu2 = new Student("Jerry",20);
ArrayList al = new ArrayList();
al.add(stu);
al.remove(stu2);
System.out.println(al.size());
}
}
class Student{
String name;
int age;
public Student(String name,int age){
this.name = name;
this.age = age;
}
public boolean equals(Object obj){
return true;
}
}
打印结果是:0
这个类覆盖了equals()方法,并返回true说明你不管删除的是不是同一个元素都会认为是同一个元素。