Java中的Queue集合

刷了一部分题,继续补习Java基础。

Queue这个英文单词就是“队列”的意思,在数据结构中,理解为“先进先出”(FIFO)。队列的头部保存在队列中存放时间最长的元素,队列的尾部保存在队列中存放时间最短的元素。新元素插入(offer)到队列的尾部,访问元素(poll)操作会返回队列头部的元素。通常,队列不允许随机访问队列中的元素。

本文中,不在展示各接口中的方法,具体的可以查询jdk 1.8的文档。

百度云链接: 

链接: https://pan.baidu.com/s/1PeWltG8XqdfpgltJeOoW2w 密码: d9xp

Queue接口有一个PriorityQueue实现类。除此之外,Queue还有一个Deque接口,Deque代表一个“双端队列”,双端队列可以同时从两端来添加、删除元素,因此Deque的实现类既可当成队列使用,也可当成栈使用。Java为Deque提供了ArrayDeque和Linked List两个实现类。

1.PriorityQueue实现类

PriorityQueue是一个比较标准的队列实现类。之所以说它是比较标准的队列实现,而不是绝对标准的队列实现,是因为PriorityQueue保存队列元素的顺序并不是按加入队列的顺序,而是按队列元素的大小进行重新排序。因此当调用peek()方法或者poll()方法取出队列中的元素时,并不是取出最先进入队列的元素,而是取出队列中最小的元素。这就违反队列的最基本原则:先进先出(FIFO)。

举个例子:

import java.util.PriorityQueue;

public class Main {

    public static void main(String[] args){
        PriorityQueue pg = new PriorityQueue();
        pg.offer(6);
        pg.offer(-1);
        pg.offer(2);
        System.out.println(pg);
        System.out.println("队列中的第一个元素:"+pg.poll());//poll()返回并删除队列的第一个元素
        System.out.println(pg);
    }
}

结果:

注意:因为PriorityQueue是进行排序的,所以不允许插入的元素为null。

2.Deque接口与ArrayDeque实现类

Deque接口是Queue接口的子接口,它代表一个双端队列。它不仅可以当成双端队列使用,而且可以被当成栈来使用。

Deque接口提供了一个典型的实现类:ArrayDeque,从该名称就可以看出,它是一个基于数组实现的双端队列,创建Deque时同样可指定一个numElements参数,该参数用于指定Object[]数组的长度;如果不指定numElements参数,Deque底层数组的长度为16。

举个例子:

ArrayDeque当成栈来使用:

import java.util.ArrayDeque;

public class Main {

    public static void main(String[] args){
        ArrayDeque stack = new ArrayDeque();
        stack.push(1);
        stack.push(2);
        stack.push(3);
        System.out.println(stack);
        System.out.println("栈顶的元素:"+stack.peek());//peek()只访问栈顶元素,并不删除
        System.out.println(stack);
        stack.pop();//删除栈顶元素
        System.out.println(stack);
    }
}

输出:

ArrayDeque当成队列来使用:

import java.util.ArrayDeque;

public class Main {

    public static void main(String[] args){
        ArrayDeque queue = new ArrayDeque();
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        System.out.println(queue);
        System.out.println("队列头部的元素为:"+queue.peek());//peek()只访问,不删除
        System.out.println(queue);
        System.out.println(queue.poll());//poll()删除头部元素
        System.out.println(queue);
    }
}

输出:

3.LinkedList实现类

LinkedList类是List接口的实现类--这意味着它是一个List集合,可以根据索引来随机访问集合中的元素。除此之外LinkedList还实现了Deque接口,可以被当成双端队列来使用,因此既可以被当成”栈“来使用,也可以当成队列使用。

例子:

import java.util.*;

public class Main {

    public static void main(String[] args){
        LinkedList test = new LinkedList();
        //将数字1加入队列的尾部
        test.offer(1);
        //将数字2加入栈的顶部
        test.push(2);
        //将数字3添加到队列的头部(相当于栈的顶部)
        test.offerFirst(3);
        //以List的方式(按索引访问的方式)来遍历集合元素
        for(int i = 0;i<test.size();i++)
            System.out.println(test.get(i));
        //访问并不删除栈顶的元素
        System.out.println("栈顶的元素:"+test.peekFirst());
        //访问并不删除队列的最后一个元素
        System.out.println("队列的最后一个元素:"+test.peekLast());
        //将栈顶的元素弹出“栈”
        test.pop();
        System.out.println(test);
        //访问并删除队列的最后一个元素
        test.pollLast();
        System.out.println(test);
    }
}

输出:

LinkedList与ArrayList、ArrayDeque的实现机制完全不同,ArrayList、ArrayDeque内部以数组的形式来保存集合中的元素,因此随机访问集合元素时有较好的性能;而LinkedList内部以链表的形式来保存集合中的元素,因此随机访问集合元素时性能较差,但在插入、删除元素时性能比较出色(只需改变指针所指的地址即可)。需要指出的是,虽然Vector也是以数组的形式来存储集合元素的,但因为它实现了线程同步功能(而且实现机制也不好),所以各方面性能比较差。

参考文献:《疯狂Java讲义》

猜你喜欢

转载自blog.csdn.net/yong_zi/article/details/81628894