一、ArrayList类
1、ArrayList类概述
底层数据结构是数组,查询操作快,增删操作慢,线程不安全,但是效率高。
2、ArrayList类的案例
案例1 :ArrayList存储字符串并遍历
方法1:用迭代器实现
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
public class Test1 {
public static void main(String[] args) {
//ArrayList 底层数据结构是数组,有序的(存的顺序和取的顺序是一致的)
ArrayList<String> list = new ArrayList<>();
list.add("迪丽热巴");
list.add("古力娜扎");
list.add("佟丽娅");
list.add("王祖贤");
//使用迭代器遍历集合
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//使用List特有的迭代器
ListIterator<String> listIterator = list.listIterator();
while (listIterator.hasNext()){
System.out.println(listIterator.next());
}
}
}
方法2:for循环遍历
import java.util.ArrayList;
public class Test2 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("迪丽热巴");
list.add("古力娜扎");
list.add("佟丽娅");
list.add("王祖贤");
//用for循环遍历
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
}
二、Vector类
1、 Vector类的概述:Vector 可实现自动增长的对象数组。
vector是STL中最常见的容器,它是一种顺序容器,支持随机访问。vector是一块连续分配的内存,从数据安排的角度来讲,和数组极其相似,不同的地方就是:数组是静态分配空间,一旦分配了空间的大小,就不可再改变了;而vector是动态分配空间,随着元素的不断插入,它会按照自身的一套机制不断扩充自身的容量。
vector的扩充机制:按照容器现在容量的一倍进行增长。vector容器分配的是一块连续的内存空间,每次容器的增长,并不是在原有连续的内存空间后再进行简单的叠加,而是重新申请一块更大的新内存,并把现有容器中的元素逐个复制过去,然后销毁旧的内存。这时原有指向旧内存空间的迭代器已经失效,所以当操作容器时,迭代器要及时更新。
2、vector的数据结构
vector数据结构,采用的是连续的线性空间,属于线性存储。他采用3个迭代器_First、_Last、_End来指向分配来的线性空间的不同范围,下面是声明3个迭代器变量的源代码。
template<class _Ty, class _A= allocator< _Ty> >
class vector{
...
protected:
iterator _First, _Last, _End;
};
_First指向使用空间的头部,_Last指向使用空间大小(size)的尾部,_End指向使用空间容量(capacity)的尾部。例如:
int data[6]={3,5,7,9,2,4};
vector<int> vdata(data, data+6);
vdata.push_back(6);
...
vector初始化时,申请的空间大小为6,存放下了data中的6个元素。当向vdata中插入第7个元素“6”时,vector利用自己的扩充机制重新申请空间,数据存放结构如图1所示:
简单描述一下。当插入第7个元素“6”时,vector发现自己的空间不够了,于是申请新的大小为12的内存空间(自增一倍),并将前面已有数据复制到新空间的前部,然后插入第7个元素。此时_Last迭代器指向最后一个有效元素,而_End迭代器指向vector的最后有效空间位置。我们利用vector的成员函数size可以获得当前vector的大小,此时为7;利用capacity成员函数获取当前vector的容量,此时为12。
3、 Java中的Vector类
Java.util.vector提供了向量类(vector)以实现类似动态数组的功能。在Java语言中没有指针的概念,但如果正确灵活地使用指针又确实可以大大提高程序的质量。比如在c,c++中所谓的“动态数组”一般都由指针来实现。为了弥补这个缺点,Java提供了丰富的类库来方便编程者使用,vector类便是其中之一。事实上,灵活使用数组也可以完成向量类的功能,但向量类中提供大量的方法大大方便了用户的使用。
创建了一个向量类的对象后,可以往其中随意插入不同类的对象,即不需顾及类型也不需预先选定向量的容量,并可以方便地进行查找。对于预先不知或者不愿预先定义数组大小,并且需要频繁地进行查找,插入,删除工作的情况。可以考虑使用向量类。
向量类提供了三种构造方法:
public vector()
public vector(int initialcapacity,int capacityIncrement)
public vector(int initialcapacity)
使用第一种方法系统会自动对向量进行管理,若使用后两种方法。则系统将根据参数,initialcapacity设定向量对象的容量(即向量对象可存储数据的大小),当真正存放的数据个数超过容量时。系统会扩充向量对象存储容量。
参数capacityincrement给定了每次扩充的扩充值。当capacityincrement为0的时候,则没次扩充一倍,利用这个功能可以优化存储。
4、Vector类特有的功能
1) 添加功能
public void addElement(Object obj)
将obj插入向量的尾部。obj可以是任何类型的对象。对同一个向量对象,亦可以在其中插入不同类的对象。但插入的应是对象而不是数值,所以插入数值时要注意将数组转换成相应的对象。
2) 更改操作
public void setElementAt(Object obj,int index)
将index处的对象设置成obj,原来的对象将被覆盖。
3) 查找操作
* public Object elementAt(int index);
查找指定索引index处的元素。
* firstElement()
查找第一个元素。
* indexOf(Object o)
返回该向量中指定元素的第一个出现的索引,或如果此向量不包含元素,则返回- 1。
* indexOf(Object o, int index)
返回这个向量中第一个出现的指定元素的索引,从 index 索引处开始查找,如果元素没有被发现,则返回-1。反之返回1。
* lastElement()
返回向量的最后一个组件。
4) 插入操作
* insertElementAt(Object obj, int index)
将指定的索引处插入元素。
案例演示:
import java.util.Vector;
public class Test1 {
public static void main(String[] args) {
Vector<String> list = new Vector<>();
//添加功能
list.addElement("迪丽热巴");
list.addElement("古力娜扎");
list.addElement("佟丽娅");
list.addElement("王祖贤");
System.out.println(list);
System.out.println("========================================");
//更改操作
list.setElementAt("新疆小姐姐",3);
System.out.println(list);
System.out.println("========================================");
//查找功能
//查找指定索引index处的元素。
String s = list.elementAt(2);
System.out.println(s);
//查找第一个元素。
String s1 = list.firstElement();
System.out.println(s1);
//查找元素的索引
int b = list.indexOf("佟丽娅");
System.out.println(b);
//从 index 索引处开始查找
int b1 = list.indexOf("古力娜扎", 0);
int b2 = list.indexOf("古力娜扎", 2);
System.out.println(b1);
System.out.println(b2);
System.out.println("========================================");
// 将指定的索引处插入元素。
list.insertElementAt("新疆的小姐姐还有谁?",list.size());
System.out.println(list);
}
}
//
三、LinkedList类
1、概述
* LinkedList是一个继承于AbstractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。
* LinkedList 实现List 接口,能进行队列操作。
* LinkedList 实现Deque接口,即能将LinkedList当作双端队列使用。
* LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
* LinkedList 实现java.io.Serializable接口,这意味着LinkedList**支持序列化**,能通过序列化去传输。
LinkedList 是非同步的。
2、LinkedList的继承关系
* LinkedList的本质是双向链表。
* LinkedList继承于AbstractSequentialList,并且实现了Dequeue接口。
* LinkedList包含两个重要的成员:header 和 size。
header是双向链表的表头,它是双向链表节点所对应的类Entry的实例。
Entry中包含成员变量: previous, next, element。其中,previous是该节点的上一个节点,next是该节点的下一个节点,element是该节点所包含的值。
size是双向链表中节点的个数。
3、LinkedList的特有功能
1) 添加功能
void addFirst(E e)//在此列表的开始处插入指定的元素。
void addLast(E e)//将指定的元素插入到列表的结束位置。
boolean offer(E e)//将指定的元素添加到列表的尾部(最后一个元素)。
boolean offerFirst(E e)//在列表的前面插入指定的元素。
boolean offerLast(E e)//在列表的结尾插入指定的元素。
void push(E e)//将一个元素推到由该列表所表示的堆栈上。
案例:
import java.util.LinkedList;
public class Test1 {
public static void main(String[] args) {
LinkedList<String> list = new LinkedList<>();
//添加功能
//1、add 系列
list.add("小龙女");
list.add(1, "杨过");
list.addFirst("李莫愁");
list.addLast("老顽童");
System.out.println(list);
System.out.println("=====================================");
//2、offer系列
list.offer("郭靖");
list.offerFirst("黄蓉");
list.offerLast("杨康");
System.out.println(list);
System.out.println("======================================");
//3、push添加方法
list.push("郭襄");
System.out.println(list);
}
}
// 运行结果
2) 查找功能
E getFirst()//返回此列表中的第一个元素。
E getLast()//返回此列表中的最后一个元素。
E peek()//检索,但不删除,此列表的头(第一个元素)。
E peekFirst()//检索,但不删除该列表的第一个元素,如果这个列表是空的,则返回null。
E peekLast()//检索,但不删除该列表的最后一个元素,如果这个列表是空的,则返回null。
案例:使用上一个案例进行查找
//查找功能
System.out.println(list.getFirst());
System.out.println(list.get(2));
System.out.println(list.peek());
final String b = list.peekFirst();
System.out.println(b);
System.out.println("==============================================");
//运行结果
3) 遍历功能
* 特有的迭代器LinkedListIterator
* 新式加强for循环(一般用于对索引不进行操作的情况下)
System.out.println("==============================================");
//遍历
//1、迭代器
ListIterator<String> listIterator = list.listIterator();
while (listIterator.hasNext()){
System.out.println(listIterator.next());
}
System.out.println("-----------------------------------------");
//2、for循环
for(String str:list){
System.out.println(str);
}