【Redis】List类型

文章目录

  • List的特点介绍
  • lpush,lpushx,rpush,rpushx命令
  • lrange命令
  • lpop和rpop
  • lindex命令
  • linsert命令
  • llen命令
  • lrem 命令
  • ltrim命令
  • lset命令
  • 阻塞版本的命令
    • blpop和brpop
  • 命令小结
  • list的内部编码
  • List的应用场景


List的特点介绍

列表相当于一个数组或者顺序表,但是不是一个简单的数组,而是接近双端队列(deque)的结构。
对于双端队列来说,头插头删和尾插尾删的效率都很高,时间复杂度是O(1).
对于普通的数组来说,只有尾插尾删的效率高一点,但是头插和头删会涉及到内存的大量操作,效率不高。
在这里插入图片描述
列表类型的特点:

    1. 列表中的元素是有序的,这意味着可以通过索引下标获取某个元素或者某个范围的元素列表,例如要获取上图第 5 个元素,可以执⾏ lindex user:1:messages 4 或者倒数第 1 个元素,lindex
      user:1:messages -1 就可以得到元素 e。

这里的有序两个字,要根据上下文区分。
很明显,列表的有序指的是元素按照一定的顺序排列的。
但是实际中的有序,可能是升序和降序,也有可能是按照某个条件进行的有序。
举个例子:假如面试官问你堆栈的区别,你这时候就先不要着急回答。
而是先反问面试官,您这里说的堆栈,是数据结构的堆栈呢,还是操作系统的堆栈呢,还是JVM中的堆栈呢?亦或者是进程地址空间的堆栈呢?
还有一个同步,同步是指通过加锁来保证线程安全的同步呢,还是IO中的同步和异步(这里的异步其实就是并发)中的同步呢?

    1. 区分获取和删除的区别,例如 lrem 1 b 是从列表中把从左数遇到的前 1 个 b 元素删除,这个操作会导致列表的⻓度从 5 变成 4;但是执⾏ lindex 4 只会获取元素,但列表⻓度是不会变化的。
    1. 列表中的元素是允许重复的。

deque的底层结构介绍如下:
在这里插入图片描述

注意区分lindex和lrem,即获取元素和删除元素的区别。

lindex 能获取到元素的值,lrem也能返回被删除的元素的值。
因为当前的list的头和尾都能高效地插入和删除元素,所以当前的List可以用来作栈和队列使用。
后端开发中,栈用的比较少,但是队列就非常重要。比如使用队列实现生产消费者模型。
还有实现消息队列。

lpush,lpushx,rpush,rpushx命令

将一个或多个元素头插到list中

lpush key element [element …]
比如:lpush key 1 2 3 4 ,插入完成后,列表的元素是4 3 2 1
返回值:插入后的list的长度。

如果key已经存在,且key对应的value不是list类型,则lpush命令会报错。
Redis中所有类型的容器都是类似效果。
时间复杂度O(1).

lpushx命令:
在 key 存在时,将⼀个或者多个元素从左侧放⼊(头插)到 list 中。不存在,直接返回

lpushx key element [element … ]

时间复杂度O(1)

rpush和rpushx,其实就是尾插入,其他的完全相同。

操作的时间复杂度也是O(1)

lrange命令

获取key对应的[start stop]区间的元素,左闭右闭。

lrange key start stop

时间复杂度O(n)
在这里插入图片描述
如果给出的下标超出范围了,在Redis中的做法是:
直接尽可能给到区间内的元素,如果下标非法,就尽可能获取对应的内容。

这就是所谓的 ”鲁棒性“:你对我越粗鲁,我表现的越棒。(其实就是容错性强了)

然而在C++中,下标超出范围,这是一个未定义行为:
1.可能导致程序崩溃
2.可能得到不合法的数据
3.可能得到看起来合法,但是是错误的数据。
4.可能得到一个恰好符合结果的数据
就像是开盲盒一样。

缺点:程序员不能第一时间发现问题,可能会出现连锁反应。
优点:效率是最高的。相比其他编程语言,比如java,对下标超范围行为会多了一个合法性验证,然后抛异常,这就导致多了一些动作。

但是人家java这样做也有优点,就是对程序员来说能更快发现问题,也就能更高效开发代码。
所以就产生了两个问题:
是机器跑得快重要呢,还是程序员开发代码更快重要呢?
肯定是程序员开发代码重要,因为涉及到了利益问题,程序员如果开发的慢了,可能要加班修bug开发代码,甚至如果搞砸了,可能要丢失年终奖。但是对程序员来说,机器跑的快不快跟我有啥关系呢,跑的慢的话,让老板多搞两台机器过来不就行了嘛。

lpop和rpop

lpop相当于头删

lpop key
返回值:返回删除后的元素,如果列表没有元素了,则返回nil
时间复杂度O(1)

rpop相当于尾删

rpop key
返回值:返回删除后的元素,如果列表没有元素了,则返回nil
时间复杂度O(1)

从Redis 6.2版本中,新增了一个count选项(当前我用的是Redis 5,暂不考虑)

lpop key [count]
表明要头删几次

lindex命令

给定下标,获取到指定下标的元素

lindex key index
支持负数下标,-1表示倒数第一个了。依次类推。
如果下标非法,返回nil
时间复杂度O(n),因为在redis的list列表不是一个简单的数组,所以不能理解成O(1)的复杂度。

linsert命令

在指定位置插入元素

linsert key <before | after> pivot element
在指定的元素pivot之前/之后,插入元素element
如果指定的元素pivot在列表中存在多个,则在从左往右搜索到的第一个pivot之前/之后插入。

llen命令

获取key对应的list的长度

llen key

lrem 命令

rem就是remove命令的缩写,就是删除命令。

lrem key count element
count是要删除的个数,element是删除的值

官方文档给定的解释如下
在这里插入图片描述
意思是:
如果count > 0,则是从头到尾开始删除等于element的元素,删count个。
如果count < 0, 则是从尾到头开始删除等于element的元素,删count个。
如果count = 0, 则是删除所有等于element的元素。

lrem返回值是被删除的元素个数。

ltrim命令

该命令是保留key对应的list的[start stop]区间内的元素(同样是左闭右闭),区间外的元素都删除。

ltrim key start stop

时间复杂度O(1),也可以理解为O(N),这个N是要删除的元素个数。

lset命令

把key对应的list列表中的index下标的元素修改成element

lset key index element
时间复杂度O(N),如果是修改头或者尾,则时间复杂度是O(1)

如果给的下标非法,则直接报错。
相比于lindex命令不同的是,lindex命令对于非法的下标不报错,而是尽可能满足。。。

阻塞版本的命令

blpop和brpop

blpop key [key …] timeout
意思是可以同时对多个key的list进行头删
返回值是成功执行blpop命令的key和其删除的元素
brpop key [key …] timeout
同理
这个timeout(必选项,单位是秒)是设置阻塞的时间,下面会详细介绍

在list中存在元素的情况下,blpop和brpop命令和lpop,rpop命令作用完全相同。
但是如果list中没有元素,则blpop和brpop会产生阻塞。
这里的阻塞很好理解,就是生产消费者模型中的阻塞。
在这里插入图片描述
这里并不是无休止地阻塞,阻塞时间由timeout决定,在阻塞期间,Redis可以执行其他命令(这是经过特殊处理的,毕竟怎么可能让两个命令阻塞住Redis处理命令时的单线程模型呢,如果阻塞住了, 其他客户端发来的命令请求就得不到执行了。

注意事项:

  • 1.如果命令设置了多个key,那么会从左到右遍历这些key,一旦有其中一个key对应的list的元素就绪了,就会马上头删该key对应的list,然后立即返回。
  • 2.如果多个客户端同时对一个key进行blpop/brpop,则最先执行命令的客户端会得到删除后的元素
    在这里插入图片描述
    所以返回值是一个二元组,一方面是告诉我这个数据是来自哪个key,一方面是告诉我这个数据是什么。

在这里插入图片描述
这种情况就是key不存在,所以阻塞住了,一旦key就绪了,就立即删除返回。
这个15.17s就是阻塞的时长。

命令小结

在这里插入图片描述

list的内部编码

其实前面的文章讲过了。在这里插入图片描述

在这里插入图片描述

List的应用场景

Redis 阻塞消息队列模型
在这里插入图片描述

分频道阻塞消息队列模型

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/904572.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

QT:qt5调用打开exe程序并获取调用按钮控件实例2025.5.7

为实现在 VS2015 的 Qt 开发环境下打开外部 exe&#xff0c;列出其界面按钮控件的序号与文本名&#xff0c;然后点击包含特定文本的按钮控件。以下是更新后的代码&#xff1a; #include <QCoreApplication> #include <QProcess> #include <QDebug> #include…

基于Jenkins的DevOps工程实践之Jenkins共享库

文章目录 前言Jenkins共享库结构1、共享库演示2、知识点补充3、实践使用共享库格式化输出日志4、groovy基础语法4.1、 什么是 Groovy&#xff1f;4.2、groovy特点4.3、运行方法4.4、标识符4.5、基本数据类型4.5.1、string类型4.5.2、list类型 4.6、函数使用4.7、正则表达式 5、…

【Qt4】Qt4中实现PDF预览

方案一&#xff1a; 在Qt4中预览PDF文件&#xff0c;你可以使用多种方法&#xff0c;但最常见和简单的方法之一是使用第三方库。Qt本身并没有内置直接支持PDF预览的功能&#xff0c;但你可以通过集成如Poppler、MuPDF等库来实现这一功能。下面我将展示如何使用Poppler库在Qt4中…

php artisan resetPass 执行密码重置失败的原因?php artisan resetPass是什么 如何使用?-优雅草卓伊凡

php artisan resetPass 执行密码重置失败的原因&#xff1f;php artisan resetPass是什么 如何使用&#xff1f;-优雅草卓伊凡 可能的原因 命令不存在&#xff1a;如果你没有正确定义这个命令&#xff0c;Laravel 会报错而不是提示”重置密码失败”用户不存在&#xff1a;’a…

ai说什么是注解,并以angular ts为例

在编程中&#xff0c;注解&#xff08;Annotation&#xff09; 是一种特殊的语法结构&#xff0c;用于为代码添加元数据&#xff08;metadata&#xff09;&#xff0c;从而在不修改代码逻辑的情况下&#xff0c;提供额外的信息或指示编译器、框架、工具如何处理这些代码。注解通…

【MySQL】-- 联合查询

文章目录 1. 简介1.1 为什么要使用联合查询1.2 多表联合查询时MySQL内部是如何进行计算的 2. 内连接2.1 语法2.2 示例 3. 外连接3.1 语法3.2 示例 4. 自连接4.1 应用场景4.2 示例4.3 表连接练习 5. 子查询5.1 语法5.2 单行子查询5.3 多行子查询5.4 多列子查询5.5 在from 子句中…

【多线程】六、基于阻塞队列的生产者消费者模型

文章目录 Ⅰ. 生产者消费者模型的概念Ⅱ. 生产者消费者模型的优点Ⅲ. 基于阻塞队列的生产者消费者模型MakefileBlock_queue.hpptask.hpptest.cpp Ⅳ. 如何理解提高了效率❓❓❓ Ⅰ. 生产者消费者模型的概念 ​ 生产者消费者模型是一种常见的并发模式&#xff0c;用于解决生产者…

【Vue】全局事件总线 TodoList 事件总线

目录 一、 实现所有组件看到x事件 二、 实现$on $off 以及 $emit 总结不易~ 本章节对我有很大的收获&#xff0c; 希望对你也是&#xff01;&#xff01;&#xff01; 本节素材已上传至Gitee&#xff1a;yihaohhh/我爱Vue - Gitee.com 全局事件总线图&#xff1a; 本节素材…

Python编程virtualenv库的简介和使用方法

Python编程virtualenv库的简介和使用方法 virtualenv和conda的区别是什么

MySQL的行级锁锁的到底是什么?

大家好&#xff0c;我是锋哥。今天分享关于【MySQL的行级锁锁的到底是什么?】面试题。希望对大家有帮助&#xff1b; MySQL的行级锁锁的到底是什么? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 MySQL的行级锁是数据库管理系统&#xff08;DBMS&#xff09;的一…

【C++游戏引擎开发】第33篇:物理引擎(Bullet)—射线检测

一、射线检测核心理论体系 1.1 射线检测的数学基础 1.1.1 参数化射线方程 射线在三维空间中的数学表达采用参数方程: r ( t ) = o + t d ^ ( t ∈ [

【操作系统】线程崩溃机制详解

在分布式系统与多线程编程的世界里&#xff0c;一个看似简单的问题却暗藏玄机&#xff1a;当某条线程突然崩溃&#xff0c;其所属进程会随之消亡吗&#xff1f;这个问题背后隐藏着操作系统与编程语言的精妙设计&#xff0c;本文将从底层原理到工程实践层层剖析。 一、线程崩溃…

无人机 | 无人机设计概述

无人机设计是一个复杂的系统工程&#xff0c;涉及空气动力学、电子技术、材料科学、控制算法等多个领域的综合应用。以下是无人机设计的主要模块和关键要素概述&#xff1a; 一、总体设计目标 任务需求定义 用途&#xff1a;航拍、物流、农业、军事侦察、环境监测等性能指标&am…

强啊!Oracle Database 23aiOracle Database 23ai:使用列别名进行分组排序!

大家好&#xff0c;这里是架构资源栈&#xff01;点击上方关注&#xff0c;添加“星标”&#xff0c;一起学习大厂前沿架构&#xff01; 从 Oracle Database 23ai 开始&#xff0c;您可以在 GROUP BY 和 HAVING 子句中直接使用列别名。此功能在早期版本的 Oracle Database 中不…

Modbus 转 IEC61850 网关

第一章 产品概述 Modbus 转 IEC61850 网关型号 SG-IEC61850-Modbus &#xff0c;是三格电子推出的工业级网关&#xff08;以 下简称盒子或网关&#xff09;&#xff0c;主要用于 Modbus RTU/TCP 数据采集、 DLT645-1997/2007 数据采集&#xff0c; 可接多功能电力仪表…

MySQL 中的 MVCC 是什么?

MySQL 中的 MVCC&#xff08;Multi-Version Concurrency Control&#xff0c;多版本并发控制&#xff09; 是一种用于实现高并发读写操作的机制&#xff0c;它通过维护数据的多个版本来解决读写冲突&#xff0c;从而在保证事务隔离性的同时&#xff0c;减少锁的使用&#xff0c…

【Python】让Selenium 像Beautifulsoup一样,用解析HTML 结构的方式提取元素!

我在使用selenium的find_element的方式去获取网页元素&#xff0c;一般通过xpath、css_selector、class_name的方式去获取元素的绝对位置。 但是有时候如果网页多了一些弹窗或者啥之类的&#xff0c;绝对位置会发生变化&#xff0c;使用xpath等方法&#xff0c;需要经常变动。…

使用xlwings将excel表中将无规律的文本型数字批量转化成真正的数字

之前我写了一篇文章excel表中将无规律的文本型数字批量转化成真正的数字-CSDN博客 是使用excel自带的操作&#xff0c;相对繁琐。 今天使用xlwings操作&#xff0c;表格如下&#xff08;有真正的数字&#xff0c;也有文本型数字&#xff0c;混在在一起&#xff09;&#xff1…

ICML 2025录取率公布,spotlight posters仅占2.6%

近日&#xff0c;ICML 2025公布了论文录用结果。本次大会共收到 12,107篇有效论文投稿&#xff0c;比去年增加了28%&#xff0c;今年录取论文3,260篇&#xff0c;录取率为 26.9%。其中仅有313篇被列为“焦点海报”&#xff08;即所有投稿中排名前2.6%的论文&#xff09;&#x…

全局网络:重构数字时代的连接范式

从局部到全局 —— 网络架构的范式革命 在全球化与数字化深度融合的今天&#xff0c;传统网络架构的 “碎片化” 问题日益凸显&#xff1a;跨地域数据流通低效、设备互联孤岛化、安全策略难以统一。 全局网络作为一种突破地域与技术边界的新型网络架构&#xff0c;正成为企业…