09. Redis 五种数据类型-列表List

20 篇文章 1 订阅

Redis 里面的List 既是一个列表也是一个双向链表, 除了可以通过序号进行元素操作之外, 还可以对其进行push/pop操作, 以实现栈和队列的功能.list 中的元素是可以重复的.redis 的列表是非常强大的,可以实现列表,栈,固定长度列表,环形列表等结构.

1. 常用命令

以下API 只适用于结构为List的key, 否则会报错.

1.1 非阻塞式命令

  • Redis 的list 不只是list,可以作为队列,栈, 双端队列等.
操作命令描述返回值
lpush/rpush $key $item [ $item…]从列表左侧或右侧压入一到多个元素, 支持批量操作如果list 不存在,则会先自动创建一个list, 返回list的总个数
lpushx/rpushx从已存在列表左侧或右侧压入一个元素,不支持批量操作如果list 存在返回list 元素总个数,否则返回nil
lpop/rpop $key从列表左侧/右侧弹出一个元素如果list 不存在或list 元素为空,则返回nil; 否则返回对应的元素
lrange $key $start $end返回list 中指定范围的多个元素,但不会删除元素左侧元素下表从0 开始, 右侧元素下表从-1 开始.
ltrim $key $start $end截取list , 只保留指定范围的元素常与lpush/rpush 配合使用以实现固定长度的集合
lindex $key $index列表的标准获取元素方式,通过元素索引获取元素索引支持正负数, 当索引大于列表长度或列表不存在时返回nil
lset $key $index $value替换列表指定下标的元素索引的可为正负数, 当索引超过了列表长度会报错
llen $key获取列表元素个数当列表不存在时返回0,否则返回列表中元素个数
lrem $key $conunt $value移除列表中conunt个值为value的元素conut 值的正负数决定了从左开始数还是从右开始数
linsert $key before/after $pivot $value从列表左侧开始,向第一个匹配到的元素前面或者后面插入一个元素.正常返回列表的个数
rpoplpush $source $destination从源列表右侧弹出一个元素并从目标列表左侧压入返回移动的元素. 可以实现环式列表

1.2 阻塞式命令

  • 阻塞式命令可以实现生产者消费者模式, 一个消息只能被一个消费者消费一次
  • 阻塞式命令主要用于当列表为空时, 命令会处于等待状态, 当队列中有数据时返回, 或者等待时间超过了设置的超时时间后退出.
操作命令描述返回值
blpop/brpop k e y [ key [ key[key …] $timeoutSecs阻塞式从左侧/右侧弹出一个元素, 可同时监听多个key返回key 和 元素的组合, timeout 为等待时间,超时后结束等待返回nil, 为0时表示永远等待
brpoplpush $source $destination $timeoutSecs阻塞式的从源队列中右侧移除一个元素并从左侧压入目标队列,同brpoplpush 相似

2. 非阻塞式命令详解

2.1 lpush/rpush

  • lpush 是从list 左侧压入元素, 当批量压入元素的时候, 元素是依次向左压人, 因此list 中存放顺序和书写相反
  • rpush 是从list 右侧压入元素, 当批量压入元素的时候, 元素是依次向右压入, 因此list中存放顺序和书写相同
# 从左侧压入五个元素
127.0.0.1:6379> lpush numbers 1 2 3 4 5
(integer) 5

# 从右侧压入五个元素
127.0.0.1:6379> rpush numbers 5 4 3 2 1
(integer) 10

# 获取list 所有元素
127.0.0.1:6379> lrange numbers 0 -1
 1) "5"
 2) "4"
 3) "3"
 4) "2"
 5) "1"
 6) "5"
 7) "4"
 8) "3"
 9) "2"
10) "1"

2.2 lpushx/rpushx

从列表左侧或右侧压入一个元素, 但

# 验证chars 不存在
127.0.0.1:6379> keys *
1) "numbers"

# 向不存在的列表 插入元素,返回0, 也不会自动创建列表
127.0.0.1:6379> lpushx chars a
(integer) 0

# 创建列表
127.0.0.1:6379> lpush chars a
(integer) 1
127.0.0.1:6379> keys *
1) "chars"
2) "numbers"

# 向已存在列表压入元素, 返回列表的元素总个数
127.0.0.1:6379> lpushx chars b
(integer) 2
127.0.0.1:6379> lpushx chars c
(integer) 3

# 查看list 元素存储情况
127.0.0.1:6379> lrange chars 0 -1
1) "c"
2) "b"
3) "a

2.3 lpop/rpop

从列表左侧/右侧弹出一个元素, 返回弹出的元素. 此元素会在list 中被删除.

# 弹出list 最左侧的元素
127.0.0.1:6379> lpop numbers
"5"

# 弹出list 最右侧的元素
127.0.0.1:6379> rpop numbers
"1"

# 弹出就相当于删除元素
127.0.0.1:6379> lrange numbers 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
5) "5"
6) "4"
7) "3"
8) "2"

2.4 lrange

  • 从列表中获取指定范围的元素列表,只是获取而不删除.
  • 元素下标从0 开始支持负数, 左侧第一个元素下标为0, 右侧元素下表为-1.
  • 获取元素范围是一个左闭右闭的区间
  • 索引的正负数取决于从左还是从右数
# 获取list 所有元素, -1 代表末尾元素
127.0.0.1:6379> lrange numbers 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
5) "5"
6) "4"
7) "3"
8) "2"

# 获取list 部分元素, 从左侧数, 第一到第四个元素
127.0.0.1:6379> lrange numbers 0 3
1) "4"
2) "3"
3) "2"
4) "1"

# 获取list 部分元素, 从右侧数, 获取第1到第三个元素
127.0.0.1:6379> lrange numbers -3 -1
1) "4"
2) "3"
3) "2"

2.5 ltrim

  • 裁剪列表, 只保留筛选范围的元素.
  • 索引也支持正负数,正负数只表示从列表左侧还算从右侧开始数
  • 常与lpush/rpush 配合使用来当需要一个固定长度的list的时候.比如绑定 lpush 和 ltrim 0 99 这两条命令,就可以保证list 一直是最多只有100 个元素的列表.
# 查看原来的元素
127.0.0.1:6379> lrange numbers 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
5) "5"
6) "4"
7) "3"
8) "2"

# 对列表进行截取,只保留从左到右的前四个元素.
127.0.0.1:6379> ltrim numbers 0 3
OK

# 查看列表生育元素
127.0.0.1:6379> lrange numbers 0 -1
1) "4"
2) "3"
3) "2"
4) "1"

2.6 lindex

  • 按索引获取元素, 索引下表可以为正负数.
  • 索引正负数只表示从左/从右数
127.0.0.1:6379> lrange numbers 0 -1
1) "0"
2) "1"
3) "2"
4) "3"
5) "4"
6) "5"

# 正向索引获取元素
127.0.0.1:6379> lindex numbers 0
"0"

# 逆向索引获取元素
127.0.0.1:6379> lindex numbers -1
"5"

# 索引下标超出列表长度之后, 返回nil
127.0.0.1:6379> LINDEX numbers 100
(nil)

2.7 lset

× 替换指定索引的元素,数组下标从0开始且支持负数

127.0.0.1:6379> lrange numbers 0 -1
1) "0"
2) "1"
3) "2"
4) "3"

# 正向索引替换
127.0.0.1:6379> lset numbers 2 a
OK

# 逆向索引替换
127.0.0.1:6379> lset numbers -1 b
OK

127.0.0.1:6379> lrange numbers 0 -1
1) "0"
2) "1"
3) "a"
4) "b"

# 索引超出了列表长度会报错
127.0.0.1:6379> lset numbers 10 10
(error) ERR index out of range

# 列表不存在也会报错
127.0.0.1:6379> lset numbers2 10 10
(error) ERR no such key

2.8 llen

  • 获取列表元素个数,当列表不存在时返回0
127.0.0.1:6379> llen numbers
(integer) 6

2.9 lrem

从列表中删除多个相同的元素,对于count 取值

  • count > 0: 从头往尾移除$count个值为 value 的元素。
  • count < 0: 从尾往头移除$count个值为 value 的元素。
  • count = 0: 移除所有值为 value 的元素。
# 列表原始元素
127.0.0.1:6379> lrange chars 0 -1
 1) "0"
 2) "a"
 3) "1"
 4) "a"
 5) "2"
 6) "a"
 7) "3"
 8) "a"
 9) "4"
10) "a"
11) "5"
12) "a"

# 从左侧删除1个a 元素
127.0.0.1:6379> lrem chars 1 a
(integer) 1
127.0.0.1:6379> lrange chars 0 -1
 1) "0"
 2) "1"
 3) "a"
 4) "2"
 5) "a"
 6) "3"
 7) "a"
 8) "4"
 9) "a"
10) "5"
11) "a"

# 从右侧删除2个a元素
127.0.0.1:6379> lrem chars -2 a
(integer) 2
127.0.0.1:6379> lrange chars 0 -1
1) "0"
2) "1"
3) "a"
4) "2"
5) "a"
6) "3"
7) "a"
8) "4"
9) "5"

# 删除所有的a元素
127.0.0.1:6379> lrem chars 0 a
(integer) 3
127.0.0.1:6379> lrange chars 0 -1
1) "0"
2) "1"
3) "2"
4) "3"
5) "4"
6) "5"

2.10 linsert

从列表左侧开始,向第一个匹配到的元素前面或者后面插入一个元素.

# 创建列表,有重复元素a,b
127.0.0.1:6379> lrange chars 0 -1
1) "a"
2) "b"
3) "a"
4) "b"
5) "c"

# 在元素a 前插入1, 只会在从左开始数的第一个元素a前插入1
127.0.0.1:6379> linsert chars before a 1
(integer) 6

# 在元素b 后插入元素2, 只会在从左到右的第一个元素后面插入2
127.0.0.1:6379> linsert chars after b 2
(integer) 7

127.0.0.1:6379> lrange chars 0 -1
1) "1"
2) "a"
3) "b"
4) "2"
5) "a"
6) "b"
7) "c"

2.11 rpoplpush

从源列表右侧弹出一个元素并从目标列表左侧压入, 返回移动的元素. 可以实现环式列表.

# 原始列表
127.0.0.1:6379> lrange chars 0 -1
1) "a"
2) "b"
3) "c"
127.0.0.1:6379> lrange numbers 0 -1
1) "0"
2) "1"
3) "2"

# 从chars 列表右侧弹出一个元素并从左侧压入numbers 列表
127.0.0.1:6379> rpoplpush chars numbers
"c"
127.0.0.1:6379> lrange numbers 0 -1
1) "c"
2) "0"
3) "1"
4) "2"
127.0.0.1:6379> lrange chars 0 -1
1) "a"
2) "b"

# 实现环式列表
127.0.0.1:6379> rpoplpush chars chars
"b"
127.0.0.1:6379> lrange chars 0 -1
1) "b"
2) "a"


3. 阻塞式命令详解

3.1 blpop/brpop

# 返回值为key 和 弹出元素的组合
127.0.0.1:6379> blpop numbers 1000
1) "numbers"
2) "0"
(30.67s)

# 阻塞超时后自动结束阻塞状态
127.0.0.1:6379> blpop numbers 1
(nil)
(1.06s)

3.2 brpoplpush

127.0.0.1:6379> brpoplpush numbers chars 1000
"0"
(6.19s)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值