zoukankan      html  css  js  c++  java
  • Java集合 使用Queue

    转载:https://www.liaoxuefeng.com/wiki/1252599548343744/1265121791832960

    队列(Queue)是一种经常使用的集合。Queue实际上是实现了一个先进先出(FIFO:First In First Out)的有序表。它和List的区别在于,List可以在任意位置添加和删除元素,而Queue只有两个操作:

    • 把元素添加到队列末尾;
    • 从队列头部取出元素。

    超市的收银台就是一个队列:

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

    • int size():获取队列长度;
    • boolean add(E)/boolean offer(E):添加元素到队尾;
    • E remove()/E poll():获取队首元素并从队列中删除;
    • E element()/E peek():获取队首元素但并不从队列中删除。

    对于具体的实现类,有的Queue有最大队列长度限制,有的Queue没有。注意到添加、删除和获取队列元素总是有两个方法,这是因为在添加或获取元素失败时,这两个方法的行为是不同的。我们用一个表格总结如下:

     throw Exception返回false或null
    添加元素到队尾 add(E e) boolean offer(E e)
    取队首元素并删除 E remove() E poll()
    取队首元素但不删除 E element() E peek()

    举个栗子,假设我们有一个队列,对它做一个添加操作,如果调用add()方法,当添加失败时(可能超过了队列的容量),它会抛出异常:

    Queue<String> q = ...
    try {
        q.add("Apple");
        System.out.println("添加成功");
    } catch(IllegalStateException e) {
        System.out.println("添加失败");
    }

    如果我们调用offer()方法来添加元素,当添加失败时,它不会抛异常,而是返回false

    Queue<String> q = ...
    if (q.offer("Apple")) {
        System.out.println("添加成功");
    } else {
        System.out.println("添加失败");
    }

    当我们需要从Queue中取出队首元素时,如果当前Queue是一个空队列,调用remove()方法,它会抛出异常:

    Queue<String> q = ...
    try {
        String s = q.remove();
        System.out.println("获取成功");
    } catch(IllegalStateException e) {
        System.out.println("获取失败");
    }

    如果我们调用poll()方法来取出队首元素,当获取失败时,它不会抛异常,而是返回null

    Queue<String> q = ...
    String s = q.poll();
    if (s != null) {
        System.out.println("获取成功");
    } else {
        System.out.println("获取失败");
    }

    因此,两套方法可以根据需要来选择使用。

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

    接下来我们以poll()peek()为例来说说“获取并删除”与“获取但不删除”的区别。对于Queue来说,每次调用poll(),都会获取队首元素,并且获取到的元素已经从队列中被删除了:

    import java.util.LinkedList;
    import java.util.Queue;
    
    public class Main {
        public static void main(String[] args) {
            Queue<String> q = new LinkedList<>();
            // 添加3个元素到队列:
            q.offer("apple");
            q.offer("pear");
            q.offer("banana");
            // 从队列取出元素:
            System.out.println(q.poll()); // apple
            System.out.println(q.poll()); // pear
            System.out.println(q.poll()); // banana
            System.out.println(q.poll()); // null,因为队列是空的
        }
    }

    如果用peek(),因为获取队首元素时,并不会从队列中删除这个元素,所以可以反复获取:

    import java.util.LinkedList;
    import java.util.Queue;
    
    public class Main {
        public static void main(String[] args) {
            Queue<String> q = new LinkedList<>();
            // 添加3个元素到队列:
            q.offer("apple");
            q.offer("pear");
            q.offer("banana");
            // 队首永远都是apple,因为peek()不会删除它:
            System.out.println(q.peek()); // apple
            System.out.println(q.peek()); // apple
            System.out.println(q.peek()); // apple
        }
    }

    从上面的代码中,我们还可以发现,LinkedList即实现了List接口,又实现了Queue接口,但是,在使用的时候,如果我们把它当作List,就获取List的引用,如果我们把它当作Queue,就获取Queue的引用:

    // 这是一个List:
    List<String> list = new LinkedList<>();
    // 这是一个Queue:
    Queue<String> queue = new LinkedList<>();

    始终按照面向抽象编程的原则编写代码,可以大大提高代码的质量。

    小结

    队列Queue实现了一个先进先出(FIFO)的数据结构:

    • 通过add()/offer()方法将元素添加到队尾;
    • 通过remove()/poll()从队首获取元素并删除;
    • 通过element()/peek()从队首获取元素但不删除。

    要避免把null添加到队列。

  • 相关阅读:
    Silverlight与WPF开发人员入门应该知道的十件事
    Silverlight4.0教程之使用鼠标右键事件和滚轮事件
    Silverlight实用窍门系列:4.Silverlight 4.0添加鼠标右键菜单和Silverlight全屏模式的进入退出。【附带源码实例】
    将moss 2007的模板文件导入到moss 2010
    Silverlight4.0教程之打印报表和图形
    .NET MessageBox 网页弹出消息框
    使用sharepoint自带的文本编辑器1
    C#开发WPF/Silverlight动画及游戏系列教程(Game Tutorial):目录
    推荐一个非常好的在线免费的 Photoshop
    Silverlight游戏设计(Game Design):目录
  • 原文地址:https://www.cnblogs.com/shadoll/p/14385960.html
Copyright © 2011-2022 走看看