五、集合——5-Queue集合

5-Queue集合

1.概述

  Queue用于模拟队列这种数据结构,队列通常是指先进先出的容器。队列的头部保存着在容器中存在时间最长的元素,在尾部保存在容器中存放时间最短的元素;新元素插入到队列的尾部,访问元素操作会返回队列头部的元素。通常情况下,队列不允许随机访问队列中的元素。

  Queue接口中定义的方法:

(1)void add(Object o):在队列尾部添加新的元素;

(2)Object element():获取队列头部的元素,但不删除该元素;

(3)boolean offer(Object o):将指定元素加入到队列尾部。当使用有容量限制的队列时,此方法比add()方法好用;

(4)Object peek():获取队列头部的元素,但不是删除该元素。如果队列为空则返回null;

(5)Object poll():获取队列头部的元素,同时删除该元素。当此队列为空时,返回null。

2.PriorityQueue实现类

(1)PriorityQueue是Queue接口的实现类,它并不是一个完全的队列集合,因为在存储过程中,PriorityQueue会根据元素的大小进行排序,类似于TreeSet;

(2)当调用poll()方法或者peek()方法时,返回的元素并不是在容器中存放时间最久的元素,而是在此容器中最小的元素;

(3)PriorityQueue不允许插入null元素,还需要对元素进行排序,它的排序方式有两种:

 1)自然排序:元素对应的类实现Comparable接口;(类似于TreeSet)

 2)定制排序:关联Comparator对象;(类似于TreeSet)

(4)PriorityQueue的简单使用:

import java.util.PriorityQueue;

public class PriorityQueueTest {
    public static void main(String[] args) {
        //创建一个PriorityQueue队列
        PriorityQueue pq = new PriorityQueue();
        //依次向pq中添加元素
        pq.offer(1);
        pq.offer(8);
        pq.offer(2);
        pq.offer(5);
        //在输出时,发现排序也并非按照升序的方式排列
        //这是由于PriorityQueue重写的toString()方法影响所致
        System.out.println(pq); 
        //循环使用poll()取出元素并删除元素
        int pqSize = pq.size();        //这里注意一下,如果在for条件中使用pq.size()这个值是在改变的
        for(int i=0;i<pqSize;i++){
            System.out.println(pq.poll());
        }
        System.out.println(pq);
    }
}

 

 

 

3.Deque接口和ArrayDeque实现类

Deque接口:

(1)Deque接口是Queue接口的子接口,它代表一个双端队列,在Deque接口中定义了许多的方法,这些方法用来从两端操作队列中的元素:

 

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Iterator;

//Deque接口中定义的方法
public class DequeTest {
    public static void main(String[] args) {
        
        Deque dq = new ArrayDeque();
        //=============================================
        //将指定元素插入到该双端队列的开头
        //也可以使用offerFirst()方法,此方法有返回值
        dq.addFirst(1);
        dq.addFirst(2);
        dq.addFirst(3);
        dq.addFirst(4);
        dq.addFirst(5);
        dq.addFirst(6);
        System.out.println(dq);    //输出6 5 4 3 2 1
        //将指定元素插入到该双端队列的结尾
        //也可以使用offerLast()方法,此方法有返回值
        dq.addLast(7);
        dq.addLast(8);
        dq.addLast(9);
        dq.addLast(10);
        dq.addLast(11);
        System.out.println(dq);    //输出6 5 4 3 2 1 7 8 9 10 11
        //=============================================
        //获取该双端队列的迭代器Iterator,该Iterator逆向迭代此双端队列
        Iterator it = dq.descendingIterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
        //=============================================
        //获取但不删除该队列的第一个元素
        //也可以使用peekFirst()方法,如果该队列为空则返回null
        System.out.println(dq.getFirst());
        //获取但不删除该队列的最后一个元素
        //也可以使用peekLast()方法,如果该队列为空则返回null
        System.out.println(dq.getLast());
        
        //=============================================
        //获取并删除该双端队列的第一个元素
        dq.pollFirst();
        System.out.println(dq);
        //获取并删除该双端队列的最后一个元素
        dq.pollLast();
        System.out.println(dq);
        
        //=============================================
        //pop出该双端队列所表示栈栈顶的元素
        System.out.println(dq.pop());
        System.out.println(dq);
        //把一个元素push到该双端队列的栈顶
        dq.push(1);
        System.out.println(dq);
        
        //=============================================
        //获取并删除该双端队列的第一个元素
        System.out.println(dq.removeFirst());
        //获取并删除该双端队列的第一次出现的元素
        System.out.println(dq.removeFirstOccurrence(1));
        System.out.println(dq);
        //获取该双端队列的最后一个元素
        System.out.println(dq.removeLast());
        System.out.println(dq);
        //获取并删除该双端队列的最后一次出现的元素
        System.out.println(dq.removeLastOccurrence(2));
        System.out.println(dq);
    }
}

 

 

 

ArrayDeque实现类:

(1)ArrayDeque是Deque接口的实现类,它是一个基于数组实现的双端队列,Deque底层数组的默认长度为16;

(2)ArrayDeque的使用:

  1)ArrayDeque作为栈使用:

import java.util.ArrayDeque;

public class ArrayDequeStack {
    public static void main(String[] args) {
        ArrayDeque stack = new ArrayDeque();
        //依次将1 2 3 push入栈中
        stack.push(1);
        stack.push(2);
        stack.push(3);
        System.out.println(stack);
        //访问栈顶的元素,并不删除
        System.out.println(stack.peek());
        //pop出栈顶的元素
        stack.pop();
        System.out.println(stack);
    }
}

 

 

 

  2)ArrayDeque作为队列使用:

import java.util.ArrayDeque;

public class ArrayDequeQueue {
    public static void main(String[] args) {
        ArrayDeque queue = new ArrayDeque();
        //依次将三个元素加入队列
        queue.offer(1);
        queue.offer(2);
        queue.offer(3);
        System.out.println(queue);
        //访问队列头部的元素,并不poll出队列
        System.out.println(queue.peek());
        //poll出队列的第一个元素
        System.out.println(queue.poll());
        System.out.println(queue);
    }
}

 

 

 

4.LinkedList实现类

(1)LinkedList实现类实现了List接口,同时也实现了Deque接口,所以它可以根据索引随机访问集合中的元素,也可以作为一个双端队列使用(即可以当成队列使用,也可以当做栈来使用);

(2)LinkedList同ArrayList、ArrayDeque相比较他们实现的方式完全不同,ArrayDeque、ArrayList是以数组的形式来保存元素的,在随机访问集合元素时有较好的性能;而LinkedList是使用链表的形式来保存元素的,因此随机访问集合元素的性能较差,但是在插入、删除元素时有较好的性能;

(3)LinkedList的简单使用:

import java.util.LinkedList;

public class LinkedListTest {
    public static void main(String[] args) {
        LinkedList list = new LinkedList();
        //将元素加入队列尾部
        list.offer(1);
        //将元素加入栈的顶部
        list.push(2);
        System.out.println(list);
        //将元素加入队列的头部,相当于栈的顶部
        list.offerFirst(3);
        //按照索引遍历集合
        for(int i = 0;i<list.size();i++){
            System.out.println(list.get(i));
        }
        //访问并不删除栈顶的元素
        System.out.println(list.peekFirst());
        //访问并不删除队列的最后一个元素
        System.out.println(list.peekLast());
        //将栈顶元素pop出栈
        list.pop();
        System.out.println(list);
        //访问并删除队列最后一个元素
        System.out.println(list.pollLast());
        System.out.println(list);
    }
}

 

 

 

5.性能分析

(1)ArrayList和LinkedList:

  随机访问集合元素时,使用ArrayList;对集合使用添加、删除操作时,使用LinkedList;

(2)有关List集合使用建议:

  1)遍历List集合元素时,对于ArrayList、Vector集合来说,使用随机访问的方式(get()方法)来遍历集合;对于LinkedList集合,应该使用迭代器(Iterator)来遍历集合;

  2)经常需要进行插入、删除操作的集合选用LinkedList集合;

  3)多个线程访问List集合时,使用Collections工具类将其包装成线程安全的集合。

posted @ 2017-08-02 20:01  丶theDawn  阅读(176)  评论(0编辑  收藏  举报