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”进栈