七,Java集合类(5)——Queue接口及其实现类

Queue集合

Queue用于模拟队列数据结构,采用“先进先出”的方式。Queue接口是继承了Collection的接口,而Queue接口下面的实现类是PriorityQueue,继承的接口是Deque,接口Deque接口的实现类是ArrayDeque,同时Deque还被LinkedList类实现。

框架结构如下图中红色区域:

PriorityQueue实现类

PriorityQueue是一个比较标准的队列实现类。之所以是比较标准的原因是PriorityQueue保存队列元素的顺序并不是按照加入队列的顺序,而是按照队列元素的大小进行重新排序。因此当调用peek()或者是poll()的方法取出队列中的元素通常都是最小的元素。值得注意的是

peek()方法取出队列头部元素时候,不删除该元素,而poll()方法取出元素时会删除元素。如果遇到队列为空的情况是,两者都会返回null

package com.practice.collection;

import java.util.PriorityQueue;

public class PriorityQueueTest {

    public static void main(String[] args) {
        PriorityQueue priorityQueue = new PriorityQueue();
        priorityQueue.offer(6);
        priorityQueue.offer(-3);
        priorityQueue.offer(20);
        priorityQueue.offer(18);
        System.out.println(priorityQueue);
        while(!priorityQueue.isEmpty()){

            System.out.println(priorityQueue.poll());
        }
    }
}

PriorityQueue不允许插入null元素,还要对队列元素进行排序,两种排序方式:

  • 自然排序:集合中的元素必须实现Comparable接口,而且应该是同一个类的多个实例,否则可能导致ClassCastException异常。
  • 定制排序:创建队列时,传入一个Comparator对象,该对象负责对队列中的所有元素进行排序。采用定制排序时不需要元素实现Comparable接口。

Deque接口

Deque接口是Queue接口的子接口,代表一个双端队列。同时Deque不仅可以作为双端队列使用,而且可以被当成栈来使用,所以可以使用出栈,入栈的方法。

程序示例将ArrayDeque当做“栈”来操作

package com.practice.collection;

import java.util.ArrayDeque;

public class ArrayDequeStack {

    public static void main(String[] args) {
        ArrayDeque stack = new ArrayDeque();
        stack.push(2);
        stack.push(5);
        stack.push(7);
        stack.push(12);
        System.out.println(stack);
        /**
         * peek(),element()该方法获取队列头部的元素,但是不删除该元素。
         * poll()该方法也是获取队列头部的元素,但是删除该元素。
         */
        System.out.println(stack.peek());
        System.out.println(stack);
        System.out.println(stack.pop());
        System.out.println(stack);
    }
}

程序示例将ArrayDeque当做“队列”来操作

package com.practice.collection;

import java.util.ArrayDeque;

public class ArrayDequeQueue {

    public static void main(String[] args) {
        ArrayDeque queue = new ArrayDeque<>();
        queue.offer("JAVA SE");
        queue.offer("JAVA EE");
        queue.offer("ORACLE 11G");
        queue.offer("NODE.JS");
        System.out.println(queue);
        System.out.println(queue.peek());
        System.out.println(queue);
        System.out.println(queue.poll());
        System.out.println(queue);
    }
}

LinkedList实现类

LinkedList类是List接口的实现类,但是同时也是Deque接口实现类,所以LinkedList既可以当做双端队列来使用,也可以当做栈来使用

package com.practice.collection;

import java.util.LinkedList;

public class LinkedListTest {

    public static void main(String[] args) {
        LinkedList books = new LinkedList<>();
        books.offer("疯狂Java讲义");
        books.push("企业级应用");
        books.offerFirst("疯狂Android讲义");
        for(int i = 0;i < books.size();i ++){
            System.out.println("遍历中:"+books.get(i));
        }
        System.out.println(books.peekFirst());
        System.out.println(books.peekLast());
        System.out.println(books);
        System.out.println(books.pollLast());
        System.out.println(books);
    }
}

LinkedList与ArrayList,ArrayDeque的底层实现方式不同,ArrayList,ArrayDeque使用数组的形式来保存集合中的元素;LinkedList是采用链表的形式实现的,LinkedList因此比较适合用于经常插入和删除的操作,而以数组实现的更加适合于随机访问。

List集合总结

  1. 如果需要遍历List集合元素,对于ArrayList,Vector集合,应该使用随机访问方法(get)来遍历集合元素,对于LinkedList,应该使用迭代器的方式来遍历。
  2. 经常插入和删除的操作来改变集合的大小,可以考虑使用LinkedList集合。使用ArrayList,Vector会经常性的重新分配内部数组的大小,效果较差。
  3. 如果在多线程的情况下使用,可以考虑使用Collections将集合包装成线程安全的集合。

你可能感兴趣的:(Java,SE)