Java中的集合Queue、LinkedList、PriorityQueue

9 篇文章 0 订阅
5 篇文章 0 订阅

Queue接口
  Queue用于模拟了队列这种数据结构,队列通常是指“先进先出”(FIFO)的容器。队列的头部保存在队列中时间最长的元素,队列的尾部保存在队列中时间最短的元素。新元素插入(offer)到队列的尾部,访问元素(poll)操作会返回队列头部的元素。通常,队列不容许随机访问队列中的元素。

Queue接口中定义了如下几个方法:

void add(Object e);   //将指定元素加入此队列的尾部。
Object element();   //获取队列头部的元素,但是不删除该元素。
boolean offer(Object e); //将指定元素加入此队列的尾部。当使用有容量限制的队列时,此方法通常比add(Object e)方法更好。
Object peek();    //获取队列头部的元素,但是不删除该元素,如果此队列为空,则返回null。
Object poll(); //获取队列头部的元素,并删除该元素,如果此队列为空,则返回null。
Object remove();   //获取队列头部的元素,并删除该元素。
  Queue有两个常用的实现类:LinkedList和PriorityQueue,下面分别介绍这两个实现类。

LinkedList
  LinkedList类是一个比较奇怪的类,它即是List接口的实现类,这意味着它是一个List集合,可以根据索引来随机访问集合中的元素。除此之外,LinkedList还实现了Deque接口,Deque接口是Queue接口的子接口,它代表一个双向队列,Deque接口里定义了一些可以双向操作队列的方法:

void addFirst(Object e); //将指定元素插入该双向队列的开头。
void addLast(Object e);  //将指定元素插入该双向队列的末尾。
Iterator descendingIterator(); //返回以该双向队列对应的迭代器,该迭代器将以逆向顺序来迭代队列中的元素。
Object getFirst();      //获取、但不删除双向队列的第一个元素。
Object getLast();   //获取、但不删除双向队列的最后一个元素。
boolean offerFirst(Object e);//将指定元素插入该双向队列的开头
boolean offerLast(Object e);//将指定元素插入该双向队列的结尾
Object peekFirst(); //获取、但不删除双向队列的第一个元素;如果此双端队列为空,则返回null。
Object peekLast(); //获取、但不删除该双向队列的最后一个元素;如果此双端队列为空,则返回null。
Object pollFirst(); //获取、并删除双向队列的第一个元素;如果此双端队列为空,则返回null。
Object pollLast(); //获取、并删除双向队列的最后一个元素,如果此双端队列为空,则返回null。
Object pop(); //pop出该双向队列所表示的栈中第一个元素。
void push(Object e); //将一个元素push进该双向队列所表示的栈中。
Object removeFirst(); //获取、并删除该双向队列的第一个元素。
Object removeFirstOccurrence(Object e); //删除该双向队列的第一次的出现元素e。
removeLast();   //获取、并删除该双向队列的最后一个元素。
removeLastOccurrence(Object e); //删除该双向队列的最后一次的出现元素e
    从以上方法可以看出,LinkedList不仅可以当成双向队列使用,也可以当成“栈”使用,因为该类还包含了pop(出栈)和push(入栈)两个方法。除此之外,LinkedList实现了List接口,所以还被当成List使用。

建议:

  1. 如果需要遍历List集合元素,对于ArrayList、Vector集合,则应该使用随机访问方法(get)来遍历集合元素,这样性能更好,对于LinkedList集合,则应该采用迭代器(Iterater)来遍历集合元素。
  2. 如果需要经常执行插入、删除操作来改变List集合大小,则应该使用LinkedList集合,而不是ArrayList。使用ArrayList、Vector集合将需要经常重新分配内存数组的大小,其时间开销往往是使用LinkedList时时间开销的几十倍,效果很差。
    如果有多条线程需要同时访问List集合中的元素,可以考虑使用Vector这个同步实现。

PriorityQueue实现类

PriorityQueue是一个比较标准的队列实现类,之所以说它是比较标准的队列实现,而不是绝对标准的队列实现是因为:PriorityQueue保存队列元素的顺序并不是按加入队列的顺序,而是按队列元素的大小进行重新排序。
因此当调用peek方法活着pull方法来取出队列中的元素时,并不是取出最先进入队列的元素,而是取出队列中最小的元素。从这个意义上看,PriorityQueue已经违反了队列的最基本原则:先进先出(FIFO)。下面程序示范了PriorityQueue队列的用法。

public class Test {
    public static void main(String[] args){
        PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
            pq.offer(3);
            pq.offer(-6);
            pq.offer(9);
            //打印结果为[-6, 3, 9]
            System.out.println(pq);
            //打印结果为-6
            System.out.println(pq.peek());
            //打印结果为-6
            System.out.println(pq.poll());
    }
}

PriorityQueue不允许插入null元素,它还需要对队列元素进行排序,队列元素有两种排序方式:自然排序、定制排序; 关于使用自然排序和定制排序与前面讲到的TreeSet集合一样。

优先队列(priority queue)

优先级队列 是不同于先进先出队列的另一种队列。每次从队列中取出的是具有最高优先权的元素。

首先它是一个队列,但是它强调了“优先”二字,所以,已经不能算是一般意义上的队列了,它的“优先”意指取队首元素时,有一定的选择性,即根据元素的属性选择某一项值最优的出队~

关于priority_queue
1,关于STL中的priority_queue:确定用top()查看顶部元素时,该元素是具有最高优先级的一个元素. 调用pop()删除之后,将促使下一个元素进入该位置.
2,如同stack和queue,priority_queue是一个基于基本序列容器进行构建的适配器,默认的序列器是vector。

priority_queue<Type,Container,Compare> //compare默认是less

常用的操作如下:

empty() 如果优先队列为空,则返回真
pop() 删除第一个元素
push() 加入一个元素
size() 返回优先队列中拥有的元素的个数
top() 返回优先队列中有最高优先级的元素

但是在使用时必须注意:priority_queue放置元素时,不会判断元素是否重复。(因为在模板的第二个参数时顺序容器,不能保证元素的唯一性)此外可以替代默认的Compare函数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值