你必须非常努力,才能看起来毫不费力!
微信搜索公众号[ CodePlayer ],一起From Zero To Hero !
前言
Redis 中的列表(List
)类型,底层是由双端队列实现,既可以作为队列,也可以作为栈。这种结构可以方便的在头尾存取元素,即使列表中已经存在了百万条记录,也能在常量时间内完成。列表也可以使用数组来实现,数组的优点是可以在常量时间内返回给定索引位置的值,但是会有空间浪费问题,需要提前分配内存,同时需考虑扩容缩容问题。Redis作为一个数据库,需要高效的把元素插入到超长列表,因此底层结构使用双端队列。下面我们就来学习List
相关命令吧!
LPUSH
可用版本:>= 1.0.0
时间复杂度: O(N),N为给定元素的个数
2.4.0版本之前只接受插入一个元素
命令格式
1
|
LPUSH key element [element ...]
|
命令描述
- 将一个或多个元素插入到表头
- 给定多个元素时,依次插入到表头,最终最后的一个元素为表头
- key不存在时,会先创建一个空列表
- key对应的value类型不是list时,返回error
返回值
常数值:插入元素后的列表长度
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# 插入多个值,最后的在表头
127.0.0.1:6379> lpush mylist hello world
(integer) 2
# 依次返回表头到表尾的值
127.0.0.1:6379> lrange mylist 0 -1
1) "world"
2) "hello"
# key对应的value不是list类型,报错
127.0.0.1:6379> set user:01 zhangsan
OK
127.0.0.1:6379> lpush user:01 hello
(error) WRONGTYPE Operation against a key holding the wrong kind of value
|
LPUSHX
可用版本:>= 2.2.0
时间复杂度: O(N),N为给定元素的个数
4.0版本之前只接受一个元素
命令格式
1
|
LPUSHX key element [element ...]
|
命令描述
只有当key存在,且对应value为列表类型时,才会将元素插入至表头
返回值
常数值:插入元素后的列表长度
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
127.0.0.1:6379> lpush mylist hello
(integer) 1
# key对应的list存在时,插入成功
127.0.0.1:6379> lpushx mylist world
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1
1) "world"
2) "hello"
# list不存在,插入失败
127.0.0.1:6379> lpushx otherlist hello
(integer) 0
127.0.0.1:6379> lrange otherlist 0 -1
(empty array)
|
RPUSH
可用版本:>= 1.0.0
时间复杂度: O(N),N为给定元素的个数
2.4.0版本之前只接受一个元素
命令格式
1
|
RPUSH key element [element ...]
|
命令描述
- 将一个或多个元素插入到表尾
- 给定多个元素时,依次插入到表尾,最终最后的一个元素为表尾
- key不存在时,会先创建一个空列表
- key对应的value类型不是list时,返回error
返回值
常数值:插入元素后的列表长度
示例
1
2
3
4
5
6
7
8
9
|
127.0.0.1:6379> flushdb
OK
# 依次插入到表尾,最终"world"为表尾
127.0.0.1:6379> rpush mylist hello world
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "world"
|
RPUSHX
可用版本:>= 2.2.0
时间复杂度: O(N),N为给定元素的个数
4.0版本之前只接受一个元素
命令格式
1
|
RPUSHX key element [element ...]
|
命令描述
只有当key存在,且对应value为列表时,才会将元素插入至表尾
返回值
常数值:插入元素后的列表长度
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> rpush mylist hello
(integer) 1
# key对应的list存在
127.0.0.1:6379> rpushx mylist world
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "world"
# key不存在
127.0.0.1:6379> rpushx otherlist hello
(integer) 0
127.0.0.1:6379> lrange otherlist 0 -1
(empty array)
|
LPOP
可用版本:>= 1.0.0
时间复杂度: O(N),N为返回元素的个数
6.2.0版本开始支持count参数,支持返回多个元素
命令格式
命令描述
- 从表头弹出一个元素,相当于移除一个元素
- 如果指定count参数,执行count次弹出操作(依赖列表长度)
- 当list元素弹出完时,相当于删除了该key
返回值
- 没指定count参数时:返回表尾第一个元素值或者nil(key不存在时)
- 指定count参数时:返回弹出的元素列表或者nil(key不存在时)
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
127.0.0.1:6379> flushdb
OK
# 添加三个元素
127.0.0.1:6379> lpush mylist one two three
(integer) 3
# 弹出一个,剩余两个
127.0.0.1:6379> lpop mylist
"three"
# 指定count为3,但是list中只剩余两个元素
127.0.0.1:6379> lpop mylist 3
1) "two"
2) "one"
# 全部弹出,相当于删除了key和list
127.0.0.1:6379> lrange mylist 0 -1
(empty array)
127.0.0.1:6379> lpushx mylist one
(integer) 0
127.0.0.1:6379> exists mylist
(integer) 0
|
RPOP
可用版本:>= 1.0.0
时间复杂度: O(N),N为返回元素的个数
6.2.0版本开始支持count参数,支持返回多个元素
命令格式
命令描述
- 从表尾弹出一个元素,相当于移除一个元素
- 如果指定count参数,执行count次弹出操作(依赖列表长度)
- 当list元素弹出完时,相当于删除了该key
返回值
- 没指定count参数时:返回表头第一个元素值或者nil(key不存在时)
- 指定count参数时:返回弹出的元素列表或者nil(key不存在时)
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> lpush mylist one two three
(integer) 3
# 表尾弹出一个元素,剩余两个
127.0.0.1:6379> rpop mylist
"one"
# 弹出3个元素(列表中只剩两个)
127.0.0.1:6379> rpop mylist 3
1) "two"
2) "three"
# 弹出完毕,key不存在了
127.0.0.1:6379> exists mylist
(integer) 0
127.0.0.1:6379> rpushx mylist one
(integer) 0
|
RPOPLPUSH
可用版本:>= 1.2.0
时间复杂度: O(1)
自6.2.0,该命令已废弃,建议使用 LMOVE,见下个命令
命令格式
1
|
RPOPLPUSH source destination
|
命令描述
- 从source表尾弹出一个元素,插入到destination表头
- 如果source不存在,不会执行操作
- 如果source和destination是同一个,相当于把表尾数据移到表头的旋转操作
返回值
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
# 准备数据
127.0.0.1:6379> LPUSH firstlist 1 2 3 4
(integer) 4
127.0.0.1:6379> lrange firstlist 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
# 执行 RPOPLPUSH 移动数据
127.0.0.1:6379> RPOPLPUSH firstlist otherlist
"1"
# 验证两个列表数据
127.0.0.1:6379> lrange firstlist 0 -1
1) "4"
2) "3"
3) "2"
127.0.0.1:6379> lrange otherlist 0 -1
1) "1"
# 再次执行 RPOPLPUSH
127.0.0.1:6379> RPOPLPUSH firstlist otherlist
"2"
127.0.0.1:6379> lrange firstlist 0 -1
1) "4"
2) "3"
127.0.0.1:6379> lrange otherlist 0 -1
1) "2"
2) "1"
# 验证同一个列表
127.0.0.1:6379> LPUSH mylist 4 3 2 1
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
# 4 被旋转到了表头
127.0.0.1:6379> RPOPLPUSH mylist mylist
"4"
127.0.0.1:6379> lrange mylist 0 -1
1) "4"
2) "1"
3) "2"
4) "3"
|
LMOVE
可用版本:>= 6.2.0
时间复杂度: O(1)
命令格式
1
|
LMOVE source destination LEFT|RIGHT LEFT|RIGHT
|
命令描述
-
从source表尾/表头弹出元素,插入到destination的表尾/表头
例如source=[a,b,c], destination=[x,y,z],执行 LMOVE source destination RIGHT LEFT, 相当于将source表尾的数据移动到destination表头,此时 source=[a,b], destination=[c,x,y,z]
-
如果source不存在,不会执行操作
-
如果source和destination是同一个列表,那么相当于列表旋转操作或者无操作(最后两个参数都为LEFT或RIGHT)
-
LMOVE LEFT RIGHT 等价于 RPOPLPUSH
返回值
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
# first 列表中的元素
127.0.0.1:6379> lrange first 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
# 执行 lmove right left, 将first表尾元素移动到second表头
127.0.0.1:6379> lmove first second right left
"4"
127.0.0.1:6379> lrange first 0 -1
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> lrange second 0 -1
1) "4"
# 执行lmove left right,将first表头元素移动到second表尾
127.0.0.1:6379> lmove first second left right
"1"
127.0.0.1:6379> lrange first 0 -1
1) "2"
2) "3"
127.0.0.1:6379> lrange second 0 -1
1) "4"
2) "1"
|
LRANGE
可用版本:>= 1.0.0
时间复杂度: O(S+N),S为start至表头的偏移量,N为元素范围
命令格式
命令描述
- 返回列表指定区间内的元素,区间以偏移量
start
和 stop
指定
- 下标从0开始,0表示第一个元素,1表示第二个元素
- 也可以使用负数表示,-1表示最后一个元素,-2表示倒第二个元素
- 指定的区间,左右都是闭区间,即[start,stop]
- start和stop超出列表范围不会报错,如果start超出列表范围,会返回空列表;如果stop超出列表范围,遍历到最后一个元素就会停止
返回值
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
127.0.0.1:6379> rpush rangelist 1 2 3
(integer) 3
127.0.0.1:6379> lrange rangelist 0 0
1) "1"
127.0.0.1:6379> lrange rangelist 0 2
1) "1"
2) "2"
3) "3"
# stop 超出列表范围
127.0.0.1:6379> lrange rangelist 0 5
1) "1"
2) "2"
3) "3"
# start 超出列表范围
127.0.0.1:6379> lrange rangelist 3 5
(empty array)
# -1 为最后一个元素
127.0.0.1:6379> lrange rangelist 0 -1
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> lrange rangelist -3 -1
1) "1"
2) "2"
3) "3"
# start>stop
127.0.0.1:6379> lrange rangelist -1 -2
(empty array)
|
LINDEX
可用版本:>= 1.0.0
时间复杂度: O(N),N为访问到该索引需遍历的元素个数,对于表头表尾N=1
命令格式
命令描述
- 根据索引,返回列表中对应的元素值
- 0为第一个元素索引,1表示第二个元素索引,以此类推
- 也可以使用负数表示,-1表示最后一个,-2表示倒第二个,以此类推
返回值
- 字符串:索引对应的元素值;索引超出列表范围,返回nil
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
127.0.0.1:6379> rpush mylist a b c d
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
127.0.0.1:6379> lindex mylist 0
"a"
127.0.0.1:6379> lindex mylist 3
"d"
# 超出范围
127.0.0.1:6379> lindex mylist 4
(nil)
127.0.0.1:6379> lindex mylist -1
"d"
|
更多
微信公众号:CodePlayer