游戏开发工具

List列表数据类型

本节引言

存储有序的字符串(从左到右),元素可以重复。可以充当队列和栈的角色。

特点

1、有顺序

2、可以重复


相关命令

1、将一个或多个值 value 从左边插入到列表 key 的表头:

不管key是否存在,都插入:lpush teacher_name_list tom frank jerry jim lucy lily

127.0.0.1:6379> lpush  teacher_name_list tom frank jerry jim lucy lily
(integer) 6
127.0.0.1:6379> LRANGE teacher_name_list 0 -1
1) "lily"
2) "lucy"
3) "jim"
4) "jerry"
5) "frank"
6) "tom"
127.0.0.1:6379>


注意下

lpush  teacher_name_list tom frank jerry jim lucy lily
等价于
lpush  teacher_name_list tom;
lpush  teacher_name_list frank;
lpush  teacher_name_list jerry;
lpush  teacher_name_list jim;
lpush  teacher_name_list lucy;
lpush  teacher_name_list lily;


只有key存在时,才插入:lpushx parent liubei

由于key:teachers不存在,所以插入失败

127.0.0.1:6379> lrange teachers 0 -1
(empty list or set)
127.0.0.1:6379> lpushx teachers gaoxinfu
(integer) 0
127.0.0.1:6379>


key:parent存在,所以插入成功

127.0.0.1:6379> lrange parent 0 -1
1) "tom"
2) "liran"
3) "gaoxinfu"
127.0.0.1:6379> lpushx parent liubei
(integer) 4
127.0.0.1:6379> 
127.0.0.1:6379> lrange parent 0 -1
1) "liubei"
2) "tom"
3) "liran"
4) "gaoxinfu"
127.0.0.1:6379>


2、返回列表 key 中指定区间内的所有元素:LRANGE teacher_name_list 0 -1

0是第一个,-1是最后一个,1是第一个,-2是倒数第二个

127.0.0.1:6379> LRANGE teacher_name_list 0 -1
1) "lily"
2) "lucy"
3) "jim"
4) "jerry"
5) "frank"
6) "tom"
127.0.0.1:6379>


3、将一个或多个值 value 从右边插入到列表 key 的表头:

不管key是否存在,都插入:RPUSH teacher_name_list gaoxinfu zhaobolun

从最后面开始插入数据

127.0.0.1:6379> RPUSH teacher_name_list gaoxinfu zhaobolun
(integer) 8
127.0.0.1:6379> lrange teacher_name_list 0 -1
1) "lily"
2) "lucy"
3) "jim"
4) "jerry"
5) "frank"
6) "tom"
7) "gaoxinfu"
8) "zhaobolun"
127.0.0.1:6379>


只有当key存在时候,才插入:rpushx parent gaoxinfu

由于key:teachers不存在,所以插入失败

127.0.0.1:6379> rpushx teachers gaoxinfu
(integer) 0
127.0.0.1:6379> lrange teachers 0 -1
(empty list or set)
127.0.0.1:6379> rpushx teachers gaoxinfu
(integer) 0
127.0.0.1:6379>


key:parent 存在,所以插入成功

127.0.0.1:6379> rpushx parent gaoxinfu
(integer) 5
127.0.0.1:6379> lrange parent 0 -1
1) "liubei"
2) "tom"
3) "liran"
4) "gaoxinfu"
5) "gaoxinfu"
127.0.0.1:6379>


4、从左边移除第一个元素:lpop teacher_name_list

127.0.0.1:6379> lrange teacher_name_list 0 -1
1) "lily"
2) "lucy"
3) "jim"
4) "jerry"
5) "frank"
6) "tom"
7) "gaoxinfu"
8) "zhaobolun"
127.0.0.1:6379> lpop teacher_name_list
"lily"
127.0.0.1:6379>


再次查询结果如下,lily被移除

127.0.0.1:6379> lrange teacher_name_list 0 -1
1) "lucy"
2) "jim"
3) "jerry"
4) "frank"
5) "tom"
6) "gaoxinfu"
7) "zhaobolun"
127.0.0.1:6379>


5、从右边移除第一个元素:rpop teacher_name_list

127.0.0.1:6379> lrange teacher_name_list 0 -1
1) "lucy"
2) "jim"
3) "jerry"
4) "frank"
5) "tom"
6) "gaoxinfu"
7) "zhaobolun"
127.0.0.1:6379> rpop teacher_name_list
"zhaobolun"


再次查询,发现zhaobolun已经被移除

127.0.0.1:6379> lrange teacher_name_list 0 -1
1) "lucy"
2) "jim"
3) "jerry"
4) "frank"
5) "tom"
6) "gaoxinfu"
127.0.0.1:6379>


6、返回指定list下标的value:lindex teacher_name_list 1

第一个下标是0,第二个下标示1

127.0.0.1:6379> lrange teacher_name_list 0 -1
1) "lucy"
2) "jim"
3) "jerry"
4) "frank"
5) "tom"
6) "gaoxinfu"
127.0.0.1:6379> lindex teacher_name_list 1
"jim"
127.0.0.1:6379> lindex teacher_name_list -1
"gaoxinfu"
127.0.0.1:6379> lindex teacher_name_list -3
"frank"
127.0.0.1:6379>


如果要返回连续的多个,使用lrange


7、返回list数组的长度:LLEN teacher_name_list

127.0.0.1:6379> LRANGE teacher_name_list 0 -1
1) "lucy"
2) "jim"
3) "jerry"
4) "frank"
5) "tom"
6) "gaoxinfu"
127.0.0.1:6379> LLEN teacher_name_list
(integer) 6
127.0.0.1:6379>


8、移除list数组中的元素:

格式

LREM key count value;


说明

根据参数 count 的值,移除列表中与参数 value 相等的元素。
count 的值可以是以下几种:
count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count 。
count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值。
count = 0 : 移除表中所有与 value 相等的值。
返回值
被移除元素的数量。 因为不存在的 key 被视作空表(empty list),所以当 key 不存在时, LREM 命令总是返回 0

127.0.0.1:6379> lrange teacher_name_list 0 -1
1) "frank"
2) "lucy"
3) "jim"
4) "jerry"
5) "frank"
6) "tom"
7) "gaoxinfu"
8) "jim"


删除从最后面数,1个值为jim的值:lrem teacher_name_list -1 jim

127.0.0.1:6379> lrem teacher_name_list -1 jim
(integer) 1


删除从最后面数,2个值为jim的值,实际上因为只有一个jim,所以返回删除个数为1:lrem teacher_name_list -2 jim

127.0.0.1:6379> lrem teacher_name_list -2 jim
(integer) 1
127.0.0.1:6379> lrange teacher_name_list 0 -1
1) "frank"
2) "lucy"
3) "jerry"
4) "frank"
5) "tom"
6) "gaoxinfu"


删除从最后面数,2个值为frank的值:lrem teacher_name_list -2 frank

127.0.0.1:6379> lrem teacher_name_list -2 frank
(integer) 2
127.0.0.1:6379> 
127.0.0.1:6379> lrange teacher_name_list 0 -1
1) "lucy"
2) "jerry"
3) "tom"
4) "gaoxinfu"


删除从最前面数,1个值为lucy的值:lrem teacher_name_list 1 lucy

127.0.0.1:6379> lrem teacher_name_list 1 lucy
(integer) 1
127.0.0.1:6379> lrange teacher_name_list 0 -1
1) "jerry"
2) "tom"
3) "gaoxinfu"
127.0.0.1:6379>


9、向list数组插入value值

在list数组中某个值之前插入值:linsert teacher_name_list before tom lucy

127.0.0.1:6379> lrange teacher_name_list 0 -1
1) "jerry"
2) "tom"
3) "gaoxinfu"
127.0.0.1:6379> linsert teacher_name_list before tom lucy
(integer) 4
127.0.0.1:6379> lrange teacher_name_list 0 -1
1) "jerry"
2) "lucy"
3) "tom"
4) "gaoxinfu"
127.0.0.1:6379>


在list数组中某个值之后插入值:linsert teacher_name_list after tom lily

127.0.0.1:6379> lrange teacher_name_list 0 -1
1) "jerry"
2) "lucy"
3) "tom"
4) "gaoxinfu"
127.0.0.1:6379> linsert teacher_name_list after tom lily
(integer) 5
127.0.0.1:6379>


10、将children数组中的最后一个元素放到parent数组的第一个元素:RPOPLPUSH children parent

127.0.0.1:6379> lrange children 0 -1
1) "lily"
2) "lucy"
3) "tom"
127.0.0.1:6379> lrange parent 0 -1
1) "liran"
2) "gaoxinfu"
127.0.0.1:6379> 
127.0.0.1:6379> RPOPLPUSH children parent
"tom"
127.0.0.1:6379> lrange children 0 -1
1) "lily"
2) "lucy"
127.0.0.1:6379> lrange parent 0 -1
1) "tom"
2) "liran"
3) "gaoxinfu"
127.0.0.1:6379>


11、blpop的使用:http://redisdoc.com/list/blpop.html

12、brpop的使用:http://redisdoc.com/list/brpop.html

13、查看存储类型:object encoding parent

127.0.0.1:6379> object encoding parent
"quicklist"
127.0.0.1:6379>


List列表存储原理

quicklist(快速列表)是ziplist 和linkedlist 的结合体。

quicklist.h,head 和tail 指向双向列表的表头和表尾

1、quicklist

1.jpg

typedef struct quicklist {
    quicklistNode *head;
    quicklistNode *tail;
    unsigned long count;        /* total count of all entries in all ziplists */
    unsigned long len;          /* number of quicklistNodes */
    int fill : QL_FILL_BITS;              /* fill factor for individual nodes */
    unsigned int compress : QL_COMP_BITS; /* depth of end nodes not to compress;0=off */
    unsigned int bookmark_count: QL_BM_BITS;
    quicklistBookmark bookmarks[];
} quicklist;


应用场景

1、时间线

1、用户浏览记录的时间线

2、网页浏览

2.jpg

2、消息队列

1、我们在存储消息的时候,lpush 压入队列

2、我们消费消息的时候,rpop 先入先出的消费消息内容

3、JVM虚拟机中的栈

1、压栈的处理:是先进后出,rpush,brpop