list 是一个链表结构,主要功能是 push、 pop、获取一个范围的所有值等等, 操作中 key 理解为链表的名字。
Redis 的 list 类型其实就是一个每个子元素都是 string 类型的双向链表。链表的最大长度是(2的 32 次方)。我们可以通过 push,pop 操作从链表的头部或者尾部添加删除元素。这使得 list 既可以用作栈,也可以用作队列。
有意思的是 list 的 pop 操作还有阻塞版本的,当我们[lr]pop 一个 list 对象时,如果 list 是空,或者不存在,会立即返回 nil。但是阻塞版本的 b[lr]pop 可以则可以阻塞,当然可以加超时时间,超时后也会返回 nil。为什么要阻塞版本的 pop 呢,主要是为了避免轮询。举个简单的例子如果我们用 list 来实现一个工作队列。执行任务的 thread 可以调用阻塞版本的 pop 去获取任务这样就可以避免轮询去检查是否有任务存在。当任务来时候工作线程可以立即返回, 也可以避免轮询带来的延迟。说了这么多,接下来看一下实际操作的方法吧。
在 key 对应 list 的头部添加字符串元素。返回 list 中元素的个数。
127.0.0.1:6379> lpush mylist Jacob
(integer) 1
127.0.0.1:6379> lpush mylist Jacob2
(integer) 2
用于去 list 的内容,开始为 0,结束为 list 长度 -1。若结束大于等于 list 长度 -1,默认为 list 长度 -1。
127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob2"
2) "Jacob"
3) "Jacob_r"
在 key 对应 list 的尾部添加字符串元素。
127.0.0.1:6379> rpush mylist Jacob_r
(integer) 3
在 key 对应 list 的特定位置之前或之后添加字符串元素。
127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob2"
2) "Jacob"
3) "Jacob_r"
127.0.0.1:6379> linsert mylist before Jacob Jacob_before
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob2"
2) "Jacob_before"
3) "Jacob"
4) "Jacob_r"
设置 list 中指定下标的元素值(下标从 0 开始)
127.0.0.1:6379> lrange mylist 0 1
1) "Jacob2"
2) "Jacob_before"
3) "Jacob"
4) "Jacob_r"
127.0.0.1:6379> lset mylist 0 Jacob1
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob1"
2) "Jacob_before"
3) "Jacob"
4) "Jacob_r"
从 key 对应 list 中删除 count 个和 value 相同的元素。 count>0 时,按从头到尾的顺序删除,具体如下:
127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob"
2) "Jacob"
3) "Jacob"
4) "Jacob"
5) "Jacob"
6) "Jacob"
7) "Jacob1"
8) "Jacob_before"
9) "Jacob"
10) "Jacob_r"
127.0.0.1:6379> lrem mylist 2 Jacob
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob"
2) "Jacob"
3) "Jacob"
4) "Jacob"
5) "Jacob1"
6) "Jacob_before"
7) "Jacob"
8) "Jacob_r"
count<0 时,按从尾到头的顺序删除,具体如下:
127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob"
2) "Jacob"
3) "Jacob"
4) "Jacob"
5) "Jacob1"
6) "Jacob_before"
7) "Jacob"
8) "Jacob_r"
127.0.0.1:6379> lrem mylist -2 Jacob
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob"
2) "Jacob"
3) "Jacob"
4) "Jacob1"
5) "Jacob_before"
6) "Jacob_r"
count=0 时,删除全部,具体如下:
127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob"
2) "Jacob"
3) "Jacob"
4) "Jacob1"
5) "Jacob_before"
6) "Jacob_r"
127.0.0.1:6379> lrem mylist 0 Jacob
(integer) 3
127.0.0.1:6379> lrange mylist 0 100
1) "Jacob1"
2) "Jacob_before"
3) "Jacob_r"
保留指定 key 的值范围内的数据。
127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob1"
2) "Jacob_before"
3) "Jacob_r"
127.0.0.1:6379> ltrim mylist 1 -1
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob_before"
2) "Jacob_r"
从 list 的头部删除元素,并返回删除元素。
127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob_before"
2) "Jacob_r"
127.0.0.1:6379> lpop mylist
"Jacob_before"
127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob_r"
从 list 的尾部删除元素,并返回删除元素。
127.0.0.1:6379> rpop mylist
"Jacob_r"
127.0.0.1:6379> lrange mylist 0 -1
(empty list or set)
从第一个 list 的尾部移除元素并添加到第二个 list 的头部,最后返回被移除的元素值,整个操作是原子的.如果第一个 list 是空或者不存在返回 nil。
127.0.0.1:6379> lpush mylist Jacob1
(integer) 1
127.0.0.1:6379> lpush mylist Jacob2
(integer) 2
127.0.0.1:6379> lpush mylist Jacob3
(integer) 3
127.0.0.1:6379> lpush mylist Jacob4
(integer) 4
127.0.0.1:6379> lpush mylist Jacob5
(integer) 5
127.0.0.1:6379> lpush mylist2 Jacob6
(integer) 1
127.0.0.1:6379> lpush mylist2 Jacob7
(integer) 2
127.0.0.1:6379> lpush mylist2 Jacob8
(integer) 3
127.0.0.1:6379> rpoplpush mylist mylist2
"Jacob1"
127.0.0.1:6379> lrange mylist 0 -1
1) "Jacob5"
2) "Jacob4"
3) "Jacob3"
4) "Jacob2"
127.0.0.1:6379> lrange mylist2 0 -1
1) "Jacob1"
2) "Jacob8"
3) "Jacob7"
4) "Jacob6"
ps:lpush 是往头部添加。
返回名称为 key 的 list 中 index 位置的元素
127.0.0.1:6379> lindex mylist2 0
"Jacob1"
返回 key 对应 list 的长度
127.0.0.1:6379> llen mylist
(integer) 4
127.0.0.1:6379> llen mylist2
(integer) 4