queue pop java_Java之集合(Queue&Stack)

使用Queue

队列(Queue)是一种经常使用的集合。Queue实际上是实现了一个先进先出(FIFO:First In First Out)的有序表。Queue只有两个操作:

把元素添加到队列末尾;

从队列头部取出元素。

在Java的标准库中,队列接口Queue定义了以下几个方法:

int size():获取队列长度;

boolean add(E)/boolean offer(E):添加元素到队尾;

E remove()/E poll():获取队首元素并从队列中删除;

E element()/E peek():获取队首元素但并不从队列中删除。

注意到添加、删除和获取队列元素总是有两个方法,这是因为在添加或获取元素失败时,这两个方法的行为是不同的。具体如下

throw Exception

返回false或null

添加元素到队尾

add(E e)

boolean offer(E e)

取队首元素并删除

E remove()

E poll()

取队首元素但不删除

E element()

E peek()

注意:不要把null添加到队列中,否则poll()方法返回null时,很难确定是取到了null元素还是队列为空。

public class QueueTest {

public static void main(String[] args) {

Queue q = new LinkedList<>();

//添加三个元素到队列

q.add("apple");

q.offer("pear");

q.offer("banana");

//从队列取出元素

//取出首元素并删除

System.out.println(q.poll());

System.out.println(q.remove());

//取出首元素但不删除

System.out.println(q.peek());

System.out.println(q.element());

}

}

LinkedList即实现了List接口,又实现了Queue接口,但是,在使用的时候,如果我们把它当作List,就获取List的引用,如果我们把它当作Queue,就获取Queue的引用:

// 这是一个List:

List list = new LinkedList<>();

// 这是一个Queue:

Queue queue = new LinkedList<>();

Deque双端队列

如果把条件放松一下,允许两头都进,两头都出,这种队列叫双端队列(Double Ended Queue),学名Deque。Java集合提供了接口Deque来实现一个双端队列,它的功能是:

既可以添加到队尾,也可以添加到队首;

既可以从队首获取,又可以从队尾获取。

我们来比较一下Queue和Deque出队和入队的方法:

Queue

Deque

添加元素到队尾

add(E e) / offer(E e)

addLast(E e) / offerLast(E e)

取队首元素并删除

E remove() / E poll()

E removeFirst() / E pollFirst()

取队首元素但不删除

E element() / E peek()

E getFirst() / E peekFirst()

添加元素到队首

addFirst(E e) / offerFirst(E e)

取队尾元素并删除

E removeLast() / E pollLast()

取队尾元素但不删除

E getLast() / E peekLast()

Deque是一个接口,它的实现类有ArrayDeque和LinkedList。

public class DequeTest {

public static void main(String[] args) {

Deque deque = new LinkedList<>();

deque.offerLast("A"); //A

deque.offerLast("B"); //A

deque.offerFirst("C"); //C

System.out.println(deque.pollFirst()); // C, 剩下A

System.out.println(deque.pollLast()); // B, 剩下A

System.out.println(deque.pollFirst()); // A

System.out.println(deque.pollFirst()); // null

}

}

PriorityQueue优先队列

PriorityQueue和Queue的区别在于,它的出队顺序与元素的优先级有关,对PriorityQueue调用remove()或poll()方法,返回的总是优先级最高的元素。

public static void main(String[] args) {

Queue q = new PriorityQueue<>();

q.offer("apple");

q.offer("pear");

q.offer("banana");

System.out.println(q.poll()); // apple

System.out.println(q.poll()); // banana

System.out.println(q.poll()); // pear

System.out.println(q.poll()); // null,因为队列为空

}

注意:PriorityQueue默认按元素比较的顺序排序(必须实现Comparable接口),也可以通过Comparator自定义排序算法(元素就不必实现Comparable接口)。

PriorityQueue允许我们提供一个Comparator对象来判断两个元素的顺序。我们以银行排队业务为例,实现一个PriorityQueue:

public class Main {

public static void main(String[] args) {

Queue q = new PriorityQueue<>(new UserComparator());

// 添加3个元素到队列:

q.offer(new User("Bob", "A1"));

q.offer(new User("Alice", "A2"));

q.offer(new User("Boss", "V1"));

System.out.println(q.poll()); // Boss/V1

System.out.println(q.poll()); // Bob/A1

System.out.println(q.poll()); // Alice/A2

System.out.println(q.poll()); // null,因为队列为空

}

}

class UserComparator implements Comparator {

public int compare(User u1, User u2) {

if (u1.number.charAt(0) == u2.number.charAt(0)) {

// 如果两人的号都是A开头或者都是V开头,比较号的大小:

return u1.number.compareTo(u2.number);

}

if (u1.number.charAt(0) == 'V') {

// u1的号码是V开头,优先级高:

return -1;

} else {

return 1;

}

}

}

class User {

public final String name;

public final String number;

public User(String name, String number) {

this.name = name;

this.number = number;

}

public String toString() {

return name + "/" + number;

}

}

使用Stack

Stack只有入栈和出栈的操作,在Java中,我们用Deque可以实现Stack的功能:

把元素压栈:push(E)/addFirst(E);

把栈顶的元素“弹出”:pop(E)/removeFirst();

取栈顶元素但不弹出:peek(E)/peekFirst()。

为什么Java的集合类没有单独的Stack接口呢?因为有个遗留类名字就叫Stack,出于兼容性考虑,所以没办法创建Stack接口,只能用Deque接口来“模拟”一个Stack了。

当我们把Deque作为Stack使用时,注意只调用push()/pop()/peek()方法,不要调用addFirst()/removeFirst()/peekFirst()方法,这样代码更加清晰。

Stack的作用

JVM会创建方法调用栈,每调用一个方法时,先将参数压栈,然后执行对应的方法;当方法返回时,返回值压栈,调用方法通过出栈操作获得方法返回值。

对整数进行进制的转换就可以利用栈。

计算中缀表达式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值