介绍
Redis中的Lists相当于双向列表,实现原理是一个双向链表(其底层是一个快速列表),即可以支持反向查找和遍历,更方便操作。插入和删除操作非常快,时间复杂度为o(1),但是索引定位很慢,时间复杂度为o(n)。Redis set 类型中成员不能重复。
应用场景
Lists的应用场景非常多,可以利用它轻松实现热销榜;可以实现工作队列(利用lists的push操作,将任务存在Lists中,然后工作线程再用pop操作将任务取出进行执行);可以实现最新列表,比如最新评论等。
命令大纲
新增(LPUSH、RPUSH、LPUSHX、RPUSHX、LINSERT、LSET)
一个或多个值插入到列表(头部\尾部)(LPUSH)
# LPUSH key element [element ...] # element 元素值 # 返回值:列表的长度 > LPUSH listtest 3 2 1 3 # RPUSH key element [element ...] # element 元素值 # 返回值:列表的长度 > RPUSH listtest 4 5 6 6
一个或多个值插入到已存在的列表(头部\尾部)(LPUSHX、RPUSHX)
LPUSHX key element [element ...] # element 元素值 # 返回值:列表的长度,不存在则返回0 > LPUSHX listtest 7 (integer) 7 RPUSHX key element [element ...] # element 元素值 # 返回值:列表的长度,不存在则返回0 > RPUSHX listtest 8 (integer) 8
指定的元素(前\后)插入元素(LINSERT)
LINSERT key BEFORE|AFTER pivot element
当指定元素不存在于列表中时,不执行任何操作
# LINSERT key BEFORE|AFTER pivot element # BEFORE 指定元素前,AFTER指定元素后 > LRANGE listtest 0 -1 1) "7" 2) "1" 3) "2" 4) "3" 5) "4" 6) "5" 7) "6" > LINSERT listtest after 4 10 (integer) 8 > LRANGE listtest 0 -1 1) "7" 2) "1" 3) "2" 4) "3" 5) "4" 6) "10" 7) "5" 8) "6" > linsert listtest before 22 1 (integer) -1
通过索引来设置元素的值(LSET)
当索引参数超出范围,或对一个空列表进行 LSET 时,返回一个错误。
# LSET key index element # > LRANGE listtest 0 -1 1) "7" 2) "1" 3) "2" 4) "3" 5) "4" 6) "10" 7) "5" 8) "7" > LSET listtest 7 8 OK > LRANGE listtest 0 -1 1) "7" 2) "1" 3) "2" 4) "3" 5) "4" 6) "10" 7) "5" 8) "8"
查询
返回指定区间内的元素(LRANGE)
LRANGE key start stop
下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。
也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
# LRANGE key start stop # 包含指定区间内的元素 > LRANGE listtest 0 -1 1) "7" 2) "1" 3) "2" 4) "3" 5) "4" 6) "5" 7) "6"
通过索引获取列表中的元素(LINDEX)
也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
# LINDEX key index # 返回值:存在则返回,不存在,返回 nil 。 > LRANGE listtest 0 -1 1) "7" 2) "1" 3) "2" 4) "3" 5) "4" 6) "10" 7) "5" 8) "8" > LINDEX listtest 2 "2" 127.0.0.1:6379> LINDEX listtest -1 "8"
移出并获取列表的(第一\最后一)个元素 (LPOP\RPOP)
# LPOP key [count] # count 移除或者返回的条数 # 返回值:不存在则返回nil > LPOP listtest 2 1) "7" 2) "1" # RPOP key [count] > RPOP listtest 2 1) "8" 2) "5"
获取列表长度(LLEN)
LLEN key
> lrange listtest 0 -1 1) "2" 2) "3" 3) "4" 4) "10" > LLEN listtest (integer) 4
移出并获取列表的(第一/最后一)个元素(BLPOP、BRPOP)
BLPOP、BRPOP 是列表的阻塞式(blocking)弹出原语
多个 key 参数时,按参数 key 的先后顺序依次检查各个列表,弹出第一个非空列表的尾部元素
BLPOP key [key ...] timeout BRPOP key [key ...] timeout # timeout :0 是无限时间
返回值:
- 假如在指定时间内没有任何元素被弹出,则返回一个 nil 和等待时长。
- 反之,返回一个含有两个元素的列表,第一个元素是被弹出元素所属的 key ,第二个元素是被弹出元素的值。
# 返回值:弹出元素所属的 key 和值 > BLPOP listtest listtest2 0 1) "listtest" 2) "3" > BRPOP listtest 0 1) "listtest" 2) "10"
移除最后一个元素,将该元素添加到一个新列表并返回(RPOPLPUSH)
RPOPLPUSH source destination # source 源list destination 目的list # 返回值:弹出的元素,不存在返回nil
> RPOPLPUSH listtest listtest2 "6"
移除最后一个元素,将该元素添加到一个新列表并返回,没有元素则阻塞(BRPOPLPUSH)
BRPOPLPUSH source destination timeout
RPOPLPUSH
阻塞版本 BRPOPLPUSH
用法与RPOPLPUSH
一样
返回值
假如在指定时间内没有任何元素被弹出,则返回一个 nil 和等待时长。 反之,返回一个含有两个元素的列表,第一个元素是被弹出元素的值,第二个元素是等待时长。
<!--#### 用途:[安全的队列](#用途:安全的队列)-->
<!--#### 用途:[循环列表](#用途:循环列表)-->
其他操作
修剪保留指定区间内的元素(LTRIM)
LTRIM key start stop # start 开始位置 stop结束位置
下标 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
返回值
命令执行成功时,返回 ok
> LRANGE listtest2 0 -1 1) "6" 2) "4" 3) "3" 4) "2" 5) "1" 6) "2" > LTRIM listtest2 1 -1 OK > LRANGE listtest2 0 -1 1) "4" 2) "3" 3) "2" 4) "1" 5) "2"
移除列表元素(LREM)
LREM key count element # element 元素
count 的值可以是以下几种:
count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count 。 count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值。 count = 0 : 移除表中所有与 value 相等的值。
返回值:
被移除元素的数量。
因为不存在的 key 被视作空表(empty list),所以当 key 不存在时, LREM 命令总是返回 0 。
> LRANGE listtest2 0 -1 1) "4" 2) "3" 3) "2" 4) "1" 5) "2" 127.0.0.1:6379> LREM listtest2 -2 2 (integer) 2 127.0.0.1:6379> LRANGE listtest2 0 -1 1) "4" 2) "3" 3) "1"