这篇博客主要介绍List集合和Queue集合
一.List集合
List集合是一个有序的可重复的集合,集合中的每个元素都对应一个索引,我们可以通过索引来访问List集合中的数据(其实可以看成一个长度可变的数组)。
List作为Collection的子接口,支持Collection的所有操作,但因为List是有序的所以新增加了一些新的操作,主要是根据索引来插入,删除,替换元素的方法。List通过equals()方法判断对象是否相等。如下面的代码所示:
package lkl;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
public class ListTest {
public static void main(String[] args){
Collection c = new HashSet();
c.add("java");
c.add("c");
c.add("c++");
List ls = new ArrayList();
ls.add(1);
ls.add(1);
ls.add(-1);
ls.add(3);
ls.add(3);
System.out.println(ls);
///void add(int index,Object e)
///将元素e插入到List中下标为index处,index值不能大于List原先的长度
ls.add(2, 4);
System.out.println(ls);
///void addAll(int index,Collection c)
///将集合c中所有元素都插入到List的index处
ls.addAll(2,c);
System.out.println(ls);
///Object get(int index)
///返回List index处的元素,这个方法可结合for循环遍历List
for(int i=0;i<ls.size();i++)
System.out.print(ls.get(i)+" ");
System.out.println();
///int indexOf(Object o):返回元素o在集合中第一次出现的位置
///int lastIndexOf(Object o):返回元素o在集合中最后一次出现的位置
System.out.println(ls.indexOf(3));
System.out.println(ls.lastIndexOf(3));
///Object remove(int index):删除并返回index处的元素
System.out.println(ls.remove(2));
System.out.println(ls);
///Object set(int index,Object e)
///用e替换index处的对象,并返回原对象
System.out.println(ls.set(1,3));
System.out.println(ls);
///List subList(int index1,int index2)
///返回处于index1和index2之间元素组成的子集
System.out.println(ls.subList(2, 5));
}
}
对于List,由于它是有序的,所以List提供了一个额外的遍历方法lsitIterator();该方法提供了反向迭代的功能,并且还可以在遍历过程中向集合中增加元素。其相比Iterator接口增加的方法如下:
boolean hasPrevious():返回该迭代器关联的集合是否还有上一个元素。
Object previous() :返回该迭代器的上一个元素
void add() :向指定位置插入一个元素
下面的代码示范了这些操作的效果:
package lkl;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;
import java.util.ListIterator;
public class ListIteratorTest {
public static void main(String[] args){
List ls = new ArrayList();
ls.add(1);
ls.add(2);
ls.add(3);
///声明一个ListIterator类型的迭代器
ListIterator lt = ls.listIterator();
///正向迭代过程
while(lt.hasNext()){
int k=(int) lt.next();
System.out.print(k+" ");
///还可以在迭代过程中插入一个元素,但插入的元素不会影响此次的遍历
if(k==2)
lt.add(4);
}
System.out.println();
System.out.println("下面是反向迭代过程");
///下面开始反向迭代过程
while(lt.hasPrevious()){
System.out.print(lt.previous()+" ");
}
System.out.println();
}
}
二.List集合的实现类:ArrayList和Vector
ArrayList和Vector是List的两个典型实现,完全支持前面所介绍的所有的操作。ArrayList和Vector都是基于数组实现的List类,所以ArrayList和Vector类封装了一个动态的允许再分配的Object[]数组。Arraylist和Vector对象使用initialCapacity参数来设置数组的长度,然后当数组满了之后,其initialCapcity会自动增加;但是如果我们要向ArrayList中添加大量元素,那么我们可以使用ecsureCapacity()方法一次性增加initialCapacity,这样可以减少分配次数,提高性能。Object[]数组默认的长度为10.
Vector与ArrayList用法几乎完全相同,只是Vector是一个古老的集合。
并且Vector还封装了一个Stack子类,用来模拟栈,其用法如下:
package lkl;
import java.util.Stack;
public class VectorStackTest {
public static void main(String[] args){
///声明一个栈
Stack st = new Stack();
///将元素入栈
st.push("c语言");
st.push("cpp");
st.push("java");
System.out.println(st);
//返回栈顶元素,但不将其出栈
System.out.println(st.peek());
System.out.println(st);
//将栈顶元素出栈,并返回
System.out.println(st.pop());
System.out.println(st);
}
}
三.Queue集合
Queue集合用于模拟队列,即满足先进先出的性质。Queue的基本操作如下面的代码所示:
package lkl;
import java.util.ArrayDeque;
import java.util.Queue;
public class QueueTest {
public static void main(String[] args){
Queue qu = new ArrayDeque();
///void add(Object e) boolean offer(Object e)
///这两个方法都可以将元素加入到队列的尾部
qu.add("c++");
qu.add("c语言");
qu.add("java");
System.out.println(qu);
///Object peek():获取队头元素但是不删除该元素
///Object poll():获取队头元素并删除该元素
System.out.println(qu.peek());
System.out.println(qu);
System.out.println(qu.poll());
System.out.println(qu);
}
}
Queue还有一个PriorityQueue的实现类,即平时我们用的优先队列。
此外Queue还有一个Qeque接口,即”双端队列”,可以从两端来添加和删除元素,因此Deque的实现类既可以当队列使用也可以当栈使用。关于Dequeu的基本操作就不一一罗列了。Deque接口提供了一个典型的实现类:ArrayDeque,一个基于数组的双端队列实现。下面示范如何将双端队列来当初栈使用,可以看出和前面Vector实现的栈用法是一样的:
package lkl;
import java.util.ArrayDeque;
public class DequeStackTest {
public static void main(String[] args){
ArrayDeque st = new ArrayDeque();
st.push(1);
st.push(2);
st.push(3);
System.out.println(st);
System.out.println(st.peek());
System.out.println(st);
System.out.println(st.pop());
System.out.println(st);
}
}
四.LinkedList实现类
LinkedList实现类是List接口的实现类,其内部用链表来保存集合中的元素,因此有非常好的插入,删除性能。而其他的List实现类随机访问性能比较好。LinkedList除了具有List的基本操作外,还实现了Dequeu接口,因此它可以被当成双端队列来使用,也可以当成栈来使用。下面的代码简单示范了LinkedList集合的用法:
package lkl;
import java.util.LinkedList;
public class LinkedListTest {
public static void main(String[] args){
LinkedList books = new LinkedList();
///将字符串加入到队列的尾部
books.offer("c++");
///将字符串元素加入到栈的顶部
books.push("java");
///将字符串加入到队列的头部(相当于栈的顶部)
books.offerFirst("c语言");
for(int i=0;i<books.size();i++)
System.out.print(books.get(i)+" ");
System.out.println();
///访问但不删除栈顶的元素
System.out.println(books.peekFirst());
///访问但不删除队列最后一个元素
System.out.println(books.peekLast());
///将栈顶的元素弹出
System.out.println(books.pop());
System.out.println(books);
///访问并删除队列的最后一个元素
System.out.println(books.pollLast());
System.out.println(books);
}
}