1 队列接口Queue 

新元素插入(offer)到队列的尾部,访问元素(poll)操作会返回队列头部的元素

public interface Queue<E> extends Collection<E> {
    boolean add(E e);
    boolean offer(E e);
    E remove();
    E poll();
    E element();
    E peek();
}
  • boolean add(E e):将指定元素加入此队列的尾部
  • boolean offer(E e):将指定元素加入此队列的尾部(使用有容量限制的队列此方法通常比add(E e)方法更好)
  • E element():获取队列头部的元素,但是不删除该元素(队列为空NoSuchElementException)
  • E peek():获取队列头部的元素,但是不删除该元素(队列为空返回null)
  • E remove():获取队列头部的元素,并删除该元素(队列为空NoSuchElementException)
  • E poll():获取队列头部的元素,并删除该元素(队列为空返回null)

1.1 优先队列PriorityQueue 

PriorityQueue实现了接口Queue,底层是最小堆

  • 二叉堆 Binary Heap:
  • 优先队列的经典问题:  

priority 英 [praɪˈɒrəti]   美 [praɪˈɔːrəti]  
n.优先事项;最重要的事;首要事情;优先;优先权;重点;(车辆的)优先通行权

自然排序(存放的元素必须是实现了Comparable接口的)

PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.offer(6);
pq.offer(-3);
pq.offer(20);
pq.offer(18);
//-3 6 18 20 
while (!pq.isEmpty()){
	System.out.print(pq.poll()+" ");
}

Lambda表达式定制排序 

PriorityQueue<Integer> pq = new PriorityQueue<Integer>((a, b) -> b - a);
pq.offer(6);
pq.offer(-3);
pq.offer(20);
pq.offer(18);
//20 18 6 -3
while (!pq.isEmpty()) {
	System.out.print(pq.poll() + " ");
}

存入队列的元素实现了Comparable接口

public class Student implements Comparable<Student> {
    private String name;
    private Integer age; 
    @Override
    public int compareTo(Student stu) {
       if(!this.age.equals(stu.age)){//age不同按照age升序排列
           return this.age - stu.age;
       }else {//age相同按照名字的字典序升序排列
           return this.name.compareTo(stu.name);
       }
    }
    //构造函数...
    //toString...
}
PriorityQueue<Student> pq = new PriorityQueue<>();
pq.offer(new Student("蔡徐坤", 18));
pq.offer(new Student("乔奶奶", 59));
pq.offer(new Student("李明", 12));
while (!pq.isEmpty()){
    System.out.println(pq.poll());
}

Student{name='a', age=12}
Student{name='ab', age=12}
Student{name='李明', age=12}
Student{name='蔡徐坤', age=18}
Student{name='乔奶奶', age=59}


2 双端队列接口Deque 

Deque接口是 Queue接口的子接口,它代表一个双端队列

public interface Deque<E> extends Queue<E> {    
    void addFirst(E e);    
    void addLast(E e);    
    boolean offerFirst(E e);    
    boolean offerLast(E e);   
    E removeFirst();    
    E removeLast();    
    E pollFirst();
    E pollLast();   
    E getFirst();
    E getLast();   
    E peekFirst();  
    E peekLast();  
    boolean removeFirstOccurrence(Object o);  
    boolean removeLastOccurrence(Object o);
    // *** Queue methods ***   
    boolean add(E e);
    boolean offer(E e);
    E remove();
    E poll();
    E element();
    E peek();
    // *** Stack methods ***
    void push(E e);
    E pop();
    // *** Collection methods ***
    boolean remove(Object o);
    boolean contains(Object o);
    public int size();
    Iterator<E> iterator();
    //
    Iterator<E> descendingIterator();
}
  • void addFirst(E e):将指定元素插入该双端队列的开头
  • void addLast(E e):将指定元素插入该双端队列的末尾
  • boolean offerFirst(E e):将指定元素插入该双端队列的开头
  • boolean offerLast(E e):将指定元素插入该双端队列的末尾
  • E peekFirst():获取但不删除该双端队列的第一个元素(队列为空返回null)
  • E peekLast():获取但不删除该双端队列的最后一个元素(队列为空返回null)
  • E getFirst():获取但不删除双端队列的第一个元素(队列为空NoSuchElementException)
  • E getLast():获取但不删除双端队列的最后一个元素(队列为空NoSuchElementException)
  • E pollFirst():获取并删除该双端队列的第一个元素(队列为空返回null)
  • E pollLast():获取并删除该双端队列的最后一个元素(队列为空返回null)
  • E removeFirst():获取并删除该双端队列的第一个元素(队列为空NoSuchElementException)
  • E removeLast():获取并删除该双端队列的最后一个元素(队列为空NoSuchElementException)
  • E pop():pop出该双端队列所表示的栈的栈顶元素(相当于removeFirst())//出栈
  • void push(E e):将一个元素push进该双端队列所表示的栈的栈顶(相当于addFirst(e))//入栈
  • boolean removeFirstOccurrence(Object o):删除该双端队列的第一次出现的元素o
  • boolean removeLastOccurrence(Object o):删除该双端队列的最后一次出现的元素o
  • Iterator<E> descendingIterator():返回该双端队列对应的迭代器(该迭代器将以逆向顺序来迭代队列中的元素)

Deque 的方法与 Queue 的方法对照表

 

Queue 的方法

Deque 的方法

将一个元素放入队列的尾部

add(e)/offer(e)

addLast(e)/offerLast(e)

从队列首部移除元素

remove()/poll()

removeFirst()/pollFirst()

返回队列首部的元素

element()/peek()

getFirst()/peekFirst()

Deque 的方法与 Stack 的方法对照表

 

Stack 的方法

Deque 的方法

元素 e 入栈

push(e)

addFirst(e)/offerFirst(e)

移除栈顶元素

pop()

removeFirst()/peekFirst()

获取栈顶元素

peek()

getFirst()/peekFirst()


2.1 Deque实现类ArrayDeque

数组实现的双端队列,numElements指定底层Objec[] 数组长度,默认为16

2.1.1 测试输出

Deque<String> stack = new ArrayDeque<>();
stack.push("蔡徐坤");
stack.push("乔奶奶");
stack.push("JAVA");

//top: [JAVA, 乔奶奶, 蔡徐坤]
System.out.println("\ntop: "+stack);

//正着输出
//JAVA 乔奶奶 蔡徐坤
stack.iterator().forEachRemaining((e) -> System.out.print(e + " "));
System.out.println();
//倒着输出
//蔡徐坤 乔奶奶 JAVA 
stack.descendingIterator().forEachRemaining((e) -> System.out.print(e + " "));

//弹出栈中所有元素
System.out.print("\ntop: ");
while (!stack.isEmpty()){
    //top: JAVA 乔奶奶 蔡徐坤 
    System.out.print(stack.pop()+" ");
}

2.1.2 当成“栈”

Deque<String> stack = new ArrayDeque<>();
// 依次将三个元素push入"栈"
stack.push("蔡徐坤");
stack.push("乔奶奶");
stack.push("JAVA");
// 输出:[JAVA, 乔奶奶, 蔡徐坤]
System.out.println(stack);
// 访问第一个元素,但并不将其pop出"栈",输出:JAVA
System.out.println(stack.peek());
// 依然输出:[JAVA, 乔奶奶, 蔡徐坤]
System.out.println(stack);
// pop出第一个元素,输出:JAVA
System.out.println(stack.pop());
// 输出:[乔奶奶, 蔡徐坤]
System.out.println(stack);

2.1.3 当成队列

Deque<String> queue = new ArrayDeque<>();
// 依次将三个元素加入队列
queue.offer("蔡徐坤");
queue.offer("乔奶奶");
queue.offer("JAVA");
// 输出:[蔡徐坤, 乔奶奶, JAVA]
System.out.println(queue);
// 访问队列头部的元素,但并不将其poll出队列“栈“,输出:蔡徐坤
System.out.println(queue.peek());
// 依然输出:[蔡徐坤, 乔奶奶, JAVA]
System.out.println(queue);
// poll出第一个元素,输出:蔡徐坤
System.out.println(queue.poll());
// 输出:[乔奶奶, JAVA]
System.out.println(queue);

2.2 Deque实现类LinkedList

2.2.1 当成“栈”

Deque<String> stack = new LinkedList<>();
// 依次将三个元素push入"栈"
stack.push("蔡徐坤");
stack.push("乔奶奶");
stack.push("JAVA");
// 输出:[JAVA, 乔奶奶, 蔡徐坤]
System.out.println(stack);
// 访问第一个元素,但并不将其pop出"栈",输出:JAVA
System.out.println(stack.peek());
// 依然输出:[JAVA, 乔奶奶, 蔡徐坤]
System.out.println(stack);
// pop出第一个元素,输出:JAVA
System.out.println(stack.pop());
// 输出:[乔奶奶, 蔡徐坤]
System.out.println(stack);

2.2.2 当成队列

Deque<String> queue = new LinkedList<>();
// 依次将三个元素加入队列
queue.offer("蔡徐坤");
queue.offer("乔奶奶");
queue.offer("JAVA");
// 输出:[蔡徐坤, 乔奶奶, JAVA]
System.out.println(queue);
// 访问队列头部的元素,但并不将其poll出队列“栈“,输出:蔡徐坤
System.out.println(queue.peek());
// 依然输出:[蔡徐坤, 乔奶奶, JAVA]
System.out.println(queue);
// poll出第一个元素,输出:蔡徐坤
System.out.println(queue.poll());
// 输出:[乔奶奶, JAVA]
System.out.println(queue);

LinkedList<String> books = new LinkedList<String>();
// 将字符串元素加入队列的尾部
books.offer("蔡徐坤");
// 将一个字符串元素加入栈的顶部
books.push("乔奶奶");
// 将字符串元素添加到队列的头部(相当于栈的顶部)
books.offerFirst("JAVA");
// 以List的方式(按索引访问的方式)来遍历集合元素
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.pop());
// 下面输出将看到队列中第一个元素被删除
System.out.println(books);
// 访问、并删除队列的最后一个元素
System.out.println(books.pollLast());
// 下面输出:[乔奶奶]
System.out.println(books);

3 上古容器Vector

 

3.1 Vector实现类Stack

Stack继承Vector

public class Stack<E> extends Vector<E> {
    public E push(E item) {}
    public synchronized E pop() {}
    public synchronized E peek() {}  
    public boolean empty() {} 
    public synchronized int search(Object o) {}
}
  • E peek():返回“栈”的第一个元素,但并不将该元素“pop”出栈
  • E pop():返回“栈”的第一个元素,并将该元素“pop”出栈
  • E push(E item):将一个元素“push”进栈