百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

万字长文详解Java数据类型系列之LinkedQueue

toyiye 2024-06-21 12:08 8 浏览 0 评论

LinkedQueue

前面我们学习了Stack,学习了ArrayList ,学习了Vector,其实Vector和ArrayList一样,都是基于数组实现的List,也就是说都是属于List 阵营的,其主要的区别是在于线程安全上,二者的底层实现都是基于数组的,stack 集合实现了数据结构Stack 的定义,底层依赖Vector 实现也就是数组,对栈顶元素的操作实际上是对数组尾部元素的操作,因为这样可以避免数据的迁移。

也就是说我们是用数组实现的Stack,今天我们学习一个和Stack同样重要的数据结构Queue,前面学习LinkedList 的时候我们注意到了LinkedList它其实实现了Queue 接口的,所以我们可以将LinkedList当做Queue来使用,那么其底层实现就是LinkedList的实现,也就是链表。

Queue 的定义

在java5中新增加了java.util.Queue接口,用以支持队列的常见操作。该接口扩展了java.util.Collection接口。 除了基本的 Collection 操作外,队列还提供其他的插入、提取和检查操作。

我们看到List ,Set 和 Queue 都是Java 集合框架的顶级接口,虽然我们今天学习的Queue 是基于LinkedList 实现的,但是为了方便理解和梳理整个集合框架我们还是将其划分到Queue 家族,LinkedList实现了Queue接 口,Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法 了,而不能直接访问 LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用。

接下来我们看一下 Queue 接口的定义

public interface Queue<E> extends Collection<E> {
		//  将指定的元素插入此队列(如果立即可行且不会违反容量限制),在成功时返回 true,如果当前没有可用的空间,则抛出 IllegalStateException。
    boolean add(E e);
    // 将指定的元素插入此队列(如果立即可行且不会违反容量限制),当使用有容量限制的队列时,此方法通常要优于 add(E),add可能无法插入元素,而只是抛出一个异常。
    boolean offer(E e);
    // 获取并移除此队列的头。
    E remove();
    //   获取并移除此队列的头,如果此队列为空,则返回 null。
    E poll();
    //  获取,但是不移除此队列的头。
    E element();
    //  获取但不移除此队列的头;如果此队列为空,则返回 null。
    E peek();
}
复制代码

Queue使用时要尽量避免Collection的add()和remove()方法,而是要使用offer()来加入元素,使用poll()来获取并移出元素。它们的优点是通过返回值可以判断成功与否,add()和remove()方法在失败的时候会抛出异常。

如果要使用队头元素而不移出该元素,使用element()或者peek()方法。

使用

因为底层是通过LinkedList 来实现的,前面我们又对LinkedList进行了非常详细的学习,所以这里我们就不探究原理什么的了,直接看一下怎么使用

其实队列是一个先进先出的这样一个数据结构,那么我们添加元素只需要插入到链表的尾部,其他的操作都是在链表的头部操作,性能也很高,单从性能这一点来看,是链表实现还是数组实现就没有那么重要了

public static void main(String[] args) {
    // Creating Queue using the LinkedList class
    Queue<Integer> numbers = new LinkedList<>();

    // offer elements to the Queue
    numbers.offer(1);
    numbers.offer(2);
    numbers.offer(3);
    System.out.println("Queue: " + numbers);

    // Access elements of the Queue
    int accessedNumber = numbers.peek();
    System.out.println("Accessed Element peek: " + accessedNumber);
    accessedNumber = numbers.element();
    System.out.println("Accessed Element element: " + accessedNumber);

    // Remove elements from the Queue
    int removedNumber = numbers.poll();
    System.out.println("Removed Element: " + removedNumber);

    System.out.println("Updated Queue: " + numbers);
}
复制代码

输出

Queue: [1, 2, 3]
Accessed Element peek: 1
Accessed Element element: 1
Removed Element: 1
Updated Queue: [2, 3]
复制代码

操作的实现

add 和 offer

我们看到本质上offer 还是使用了LinkedList的add 方法,如果你对LinkedList有什么不清楚的话,可以看前面的文章

/**
 * Adds the specified element as the tail (last element) of this list.
 *
 * @param e the element to add
 * @return {@code true} (as specified by {@link Queue#offer})
 * @since 1.5
 */
public boolean offer(E e) {

    return add(e);
}
/**
 * Appends the specified element to the end of this list.
 *
 * <p>This method is equivalent to {@link #addLast}.
 *
 * @param e element to be appended to this list
 * @return {@code true} (as specified by {@link Collection#add})
 */
public boolean add(E e) {
  	// 添加到队列的尾部
    linkLast(e);
    return true;
}

复制代码

peek 和 element 以及poll 和 remove

之所有将这个三个方法放到一起说是因为这三分方法都是对队列的头部进行操作,这个三个方法的实现基本一样的,poll 因为是要删除队列头部的元素,所以多调用了一步unlinkFirst,也就是在删除之后给"队列选择了新的头领"

/**
 * Retrieves, but does not remove, the head (first element) of this list.
 *
 * @return the head of this list, or {@code null} if this list is empty
 * @since 1.5
 */
public E peek() {
    final Node<E> f = first;
    return (f == null) ? null : f.item;
}


/**
 * Retrieves, but does not remove, the head (first element) of this list.
 *
 * @return the head of this list
 * @throws NoSuchElementException if this list is empty
 * @since 1.5
 */
public E element() {
     final Node<E> f = first;
    if (f == null)
        throw new NoSuchElementException();
    return f.item;
}



    /**
 * Retrieves and removes the head (first element) of this list.
 *
 * @return the head of this list, or {@code null} if this list is empty
 * @since 1.5
 */
public E poll() {
    final Node<E> f = first;
    return (f == null) ? null : unlinkFirst(f);
}

public E remove() {
    final Node<E> f = first;
    if (f == null)
        throw new NoSuchElementException();
    return unlinkFirst(f);
}

private E unlinkFirst(Node<E> f) {
    // assert f == first && f != null;
    final E element = f.item;
    final Node<E> next = f.next;
    f.item = null;
    f.next = null; // help GC
    first = next;
    if (next == null)
        last = null;
    else
        next.prev = null;
    size--;
    modCount++;
    return element;
}
复制代码

总结

  1. 这一节的知识很简单,主要就是想告诉大家Queue的实现方式以及它是怎么实现的,注意和Stack 进行对比。
  2. LinkedList 实现的Queue 是一个无界的队列,所以add 和 offer 方法的效果是一样的,但是remove 和 poll还是有点差异的,poll 使用起来更加安全。
  3. Queue使用时要尽量避免Collection的add()和remove()方法而是要使用offer()来加入元素,使用poll()来获取并移出元素。它们的优点是通过返回值可以判断成功与否,add()和remove()方法在失败的时候会抛出异常

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码