列表简单说明
Redis的列表(list)是一种线性的有序结构,可以按照元素被推入列表中的顺序来存储元素,这些元素既可以是文字数据也可以是二进制数据,并且列表中的元素可以重复出现。
Redis为列表提供了丰富的操作命令,通过这些命令用户可以:
- 将新元素推出列表的左端或者右端。
- 移除位于列表最左端或者最右端的元素。
- 移出列表最右端的元素,然后把被移除的元素推入另一个列表的左端。
- 获取列表包含的元素数量。
- 获取列表,在指定索引上的单个元素或者获取列表在指定索引范围内的多个元素。
- 对列表进行修剪,只保留指定索引范围内的元素。
- 为列表的指定索引设置新元素,或者把新元素添加到某个指定元素的前面或者后面。
- 从列表中移除指定元素
- 执行能够阻塞客户端的推出和移除操作。
列表命令说明
lpush、rpush:将元素推入到列表左端、右端
用户可以通过lpush命令,将一个或多个元素推入指定列表的左端
lpush key item [item ...]
在推入操作执行完毕后,lpush命令会返回列表当前包含的元素数量作为返回值。
下图示例,展示lpush命令每次推入一个元素的过程
上图示例:
- 在执行第一次lpush之前,todo-list列表为空,里面没有元素
- 执行第一次lpush之后,将元素"buy some milk"插入到列表左端,执行完后,列表中有1个元素
- 执行第二次lpush之后,将元素"go to school"插入到列表左端,执行完后,列表中有2个元素
- 执行第三次lpush之后,将元素"go home"插入到列表左端,执行完成后,列表中有3个元素
执行完3次lpush后,todo-list列表元素如下
lpush命令允许用户一次将多个元素推入列表左端:如果用户在执行lpush命令时给定了多个元素,那么lpush命令将按照元素给定的顺序,从左到右依次将所有给定元素推入列表左端。
下图示例,展示lpush命令一次推入多个元素过程
将上面三次推入的元素,使用命令 lpush todo-lists "buy some milk" "go to school" "go home" 这次一次性推入到键为todo-lists的列表当中
因多个元素,会依次推入到列表todo-lists的最左端,3个元素推入完成后,效果如下
rpush命令和lpush命令类似,这两个命令执行的都是元素推入操作,这里就不再展示具体使用示例了。唯一区别就是lpush命令会将元素推入到列表左端,而rpush命令会将元素推入到列表右端,同样允许一次推入一个元素和一次推入多个元素。
rpush key item [item ...]
在推入操作执行完毕后,rpush命令会返回列表当前包含的元素数量作为返回值。
之前有提,Redis的列表结构中,允许重复的元素,示例看一下
在todo-list里面,继续推入"go home"元素两次,整体todo-list的元素数量变为了5,列表中有3个"go home"
lpushx、rpushx:只对已存在的列表执行推入操作
当用户调用lpush命令或rpush命令的时候,如果给定的列表key不存在的时候,命令会自动创建一个空列表,并将元素推入刚新建的空列表中。
上面示例,list1和list2均为不存在的列表,在使用命令lpush和rpush的时候,均会先创建列表,然后再推入元素,最终返回列表中元素的个数。
与lpush和rpush命令会自动创建空列表不同,lpushx和rpushx命令只在列表已经存在的情况下插入元素。
lpushx命令在列表存在的情况下,将元素推入到列表的左端
lpushx key item [item ...]
推入成功,则返回列表当前的元素个数;如果推入失败,则返回0
示例中,list3是不存在的列表,使用lpushx list3 "element" 推入元素的时候,会显示推入失败,结果返回0。再给存在的列表list2推入元素的时候,可以正常推入,推入后显示列表长度2。
rpushx命令与lpushx命令类似,在列表存在的情况下,将元素推入到列表的右端。
lpop、rpop:弹出列表最左端、右端的元素
用户可以通过lpop命令移除位于列表左端的元素,并将被移除的元素返回给用户。
lpop list
继续使用之前的todo-list列表来做lpop示例,之前todo-list中元素情况如下
依次使用lpop命令两次
继续两次lpop命令后,todo-list中由5个元素减为了三个元素。
如果用户给定的列表key不存在,那么lpop命令将返回一个空值,表示列表为空,没有元素可以弹出。
用户可以通过rpop命令移除位于列表右端的元素,并将被移除的元素返回给用户,rpop命令用法与lpop类似,这里不再展示示例。
rpop list
rpoplpush:将右端弹出的元素推入左端
rpoplpush命令操作的是两个列表,它的行为和它的名字一样,首先使用rpop命令将源列表最右端的元素弹出,然后使用lpush命令将被弹出的元素推入目标列表左端,使之成为目标列表的最左端元素
rpoplpush source-list target-list
rpoplpush命令会返回被弹出的元素作为结果
下面通过一个示例,展示rpoplpush命令的用法,将列表list3的最右端元素弹出,然后将其推入列表list4的左端。
上图示例:
- 在rpoplpush命令操作之前,list3和list4各包含3个元素
- 执行第一次rpoplpush命令,弹出list3的最右端元素c,并将其推入list4的最左端
- 执行第二次rpoplpush命令,弹出list3的最右端元素b,并将其推入list4的最左端
- 执行第三次rpoplpush命令,弹出list3的最右端元素a,并将其推入list4的最左端
- 执行完三次rpoplpush命令后,list3变为了空列表,list4包含6个元素
rpoplpush命令允许用户将源列表和目标列表设置成同一个列表,在这种情况下命令的效果相当于将列表最右端的元素变成列表最左端的元素。
下面示例,展示对同一个列表使用rpoplpush命令
上图示例:
- 在rpoplpush命令操作之前,列表包含 a b c 三个元素
- 执行第一次rpoplpush命令,将最右端元素c变为最左端,结果为c a b
- 执行第二次rpoplpush命令,将最右端元素b变为最左端,结果为b c a
- 执行第三次rpoplpush命令,将最右端元素a变为最左端,结果为a b c
- 执行完三次rpoplpush命令后,列表又重新回到了原来的样子
通过上面示例,对同一个列表重复执行rpoplpush命令操作,会创建出一个对元素进行轮换的列表,并且当对一个N个元素的列表重复执行N次之后,列表元素的排列顺序将变回原来的样子。
llen:获取列表长度
用户可以通过llen命令来获取列表的长度,即列表包含的元素的数量。
llen list
lindex:获取指定索引上的元素
Redis列表包含的每个元素都有与之对应的正数索引和复数索引,索引的范围与string的索引范围相似。
-
正数索引从列表的左端开始计算,依次向右端递增,最左端的元素索引为0,左端排第二的元素,所以为一左端排第三的元素索引为2,以此类推,最大的正数索引为列表长度减1,即N-1。
- 负数从列表的最右端开始计算,依次向左端递减,最右端元素的索引为-1,左端排行第二的元素索引为-2,右端排行第三的元素索引为-3,以此类推,最大的负数索引为列表长度的负数,即-N。
为了让用户可以方便地取到索引对应的元素,Redis提供了lindex命令
lindex list index
这个命令接受一个列表和一个索引作为参数,然后返回列表在给定索引上的元素;其中给定的索引可以是整数,可以是负数。
对于一个长度为N的非空列表来说:
- 它的正数索引必然大于等于0,并且小于等于N-1
- 它的负数索引必然小于等于-1,并且大于等于-N
如果用户给定的索引超过了这一范围,那么lindex命令将返回空值,以此来表示指定索引上并不存在任何元素。
lrange:获取指定索引范围上的元素
用户除了可以使用lindex命令来获取给定索引上的单个元素外,还可以使用lrange命令获取给定索引范围上的多个元素。
lrange list start end
lrange命令接受一个列表,一个开始索引,一个结束索引作为参数,然后依次返回列表从开始索引到结束索引范围内的所有元素,其中开始索引和结束索引对应的元素都会被包含在命令返回的元素当中。
一个快捷地获取列表包含的所有元素的方法,就是使用0作为开始索引,-1作为结束索引去调用lrange命令,这种方法非常适合查看长度较短的列表
与lindex命令一样,lrange命令会处理索引超出范围的情况
- 如果用户给定的起始索引和结束索引都超过了范围,那么lrange命令将返回空列表作为结果。
- 如果用户给定的其中一个索引超出了范围,那么lrange命令将对超过范围的索引进行修正,然后再执行实际的范围获取操作;其中超出范围的起始索引会被修正为0,超出范围的结束索引会被修正为-1。
上图示例,alphabets列表长度为7,正数索引为0到6,负数索引为-7到-1。当取索引在8到10或-10到-8的时候,起始和结束索引均超出了列表的索引范围,会返回空列表;当取索引范围在-10到-6的时候,因结束索引-6在有效范围内,其实索引超出,修正其实索引-10为-7,实际命令为lrange alphabets -7 -6,取到a 和 b两个元素;当取索引范围5到8时候,因结束索引8超过最大索引6,修正结束索引为6,实际命令为lrange alphabets 5 6,取到 f 和 g两个元素。
lset:为指定索引设置新元素
用户可以通过lset命令,为列表的指定索引位置设置新元素
lset list index new_element
lset命令在设置成功时将返回OK。
lset命令只能对列表中已存在的索引进行设置,所以如果用户给定的索引超出了列表的有效索引范围,那么lset命令将返回一个错误
linsert:将元素插入列表
通过使用linsert命令,用户可以将一个新元素插入列表某个指定元素的前面或者后面
linsert list before|after target_element new_element
linsert 第二个参数的值可以是before或者after,它们分别用于表示命令将新元素插入目标元素的前面或者后面,命令在完成插入操作之后会返回列表当前的长度。
上图示例,列表ls中包含元素 c b a,使用linsert ls before a 123 向a元素前面插入元素123,插入成功后,ls列表长度变为4。
上面示例中,给a元素前面插入元素时候,列表中只有一个a,如果列表中有重复的元素,插入的时候会怎么处理,看个示例
给ls列表中再推入一个元素b,ls中元素依次为 b c b 123 a,此时使用linsert ls before b "hello world" 向b元素前面插入"hello world",因列表中有两个b,插入成功后,使用lrange 0 -1查看列表所有元素,可以看到新元素"hello world"插入到列表中第一个b元素的前面。此示例说明,linsert在向列表中插入元素的时候,会在找到的第一个元素位置处做处理。
上图示例,展示after参数的使用。
为了执行插入操作,linsert命令要求用户给定的目标元素必须已经存在于列表当中。如果用户给定的目标元素并不存在,那么linsert 命令将返回-1表示插入失败。
上图示例中,列表中不包含元素d,向元素d后面插入元素redis,因为d不存在,插入失败,返回-1。
使用命令linsert no-exists-list before a a向不存在的列表中插入元素,返回0。
在插入操作执行失败的情况下,列表包含的元素将不会发生任何变化。
ltrim:修剪列表
ltrim命令接受一个列表和一个索引范围作为参数,并移除列表中位于给定索引范围之外的所有元素,只保留给定范围之内的元素
ltrim list start end
ltrim命令在执行完移除操作之后将返回OK作为结果。
上图示例,创建reimls列表,其中推入11个元素,使用ltrim trimls 0 6 截取索引范围0到6的7个元素。
与lrange类似,ltrim命令不仅可以处理正数索引,亦可以处理负数索引。
下图示例,展示ltrim命令对于负数索引的使用,使用ltrim命令获取列表后5个元素。
lrem:从列表中移除指定元素
用户可以通过lrem命令移除列表中的指定元素
lrem list count element
count参数决定了lrem命令移除元素的方式:
- 如果count参数的值等于0,那么lrem命令将移除列表中包含的所有指定元素
- 如果count参数的值大于0,那么lrem命令将从列表的左端开始向右进行检查,并移除最先发现的count个指定元素
- 如果count参数的值小于0,那么lrem命令将从列表的右端开始向左进行检查,并移除最先发现的abs(count)个指定元素(abs(count) 即count的绝对值)
lrem命令在执行完毕之后将返回被移除的元素数量作为命令的返回值。
下面示例,展示count值为0情况
示例中,有列表remls,包含元素 a b b a c c a,使用命令lrem remls 0 a 移除列表中所有的a,列表中有3个a,命令结果返回3,移除后,使用lrange remls 0 -1查看到列表结果中不在含有a。
下面示例,展示count大于0情况
示例中,有列表remls2,包含元素 a b b a c c a,使用命令lrem remls2 2 a 移除列表靠近左端的2个元素a,命令结果返回2。
下面示例,展示count小于0情况
示例中,有列表remls3,包含元素 a b b a c c a,使用命令lrem remls3 -2 a 移除列表靠近右端的2个元素a,命令结果返回2。
列表使用总结
1、Redis的列表是一种线性的有序结构,可以按照元素推入列表中的顺序来存储元素,并且列表中的元素可以重复出现
2、用户可以使用lpush、rpush、rpop、lpop等命令,从列表的两端推入或者弹出元素,也可以通过linsert命令将新元素插入列表已有元素的前面或者后面
3、用户可以使用lrem命令从列表中移除指定的元素,或者使用ltrim命令对列表进行修剪
4、使用lrange命令查看列表指定索引范围内元素信息,使用lrange查看列表所有元素。
5、当用户传给lrange命令的索引范围超出了列表的有效索引范围时,lrange命令将对传入的索引范围进行修正,并根据修正后的索引范围来获取列表元素。