the-way-to-go - 3. Redis 数据类型: List 列表

简介: the-way-to-go - 3. Redis 数据类型: List 列表

Redis 数据类型: List 列表

  1. 单键多值
  2. Redis 列表是简单的 字符串列表 ,按照插入顺序排序。你可以添加一个元素到列表的 头部(左边) 或者 尾部(右边)
  3. 它的底层实际是个 双向链表 ,对两端的操作性能很高,通过索引下标的操作 中间的节点性能会较差

20220311102948

常用命令

把双向链表想象成一根水管, 加入数据 (Push) 就是向水管里 放入 乒乓球。 弹出数据(Pop) 就是从水管理 拿出 乒乓球。

由于可以左右两边分别操作, 因此使用 L / R 表示方向

20220311102927

添加数据 LPush and RPush

LPush 从左侧加入数据, RPush 从右侧加入数据。 一次操作可以 添加 多个数据。

LPUSH key element [element ...]
RPUSH key element [element ...]

从下面案例可以得知, 无论从左右侧添加, 先添加的数据都更靠中间

127.0.0.1:6379[10]> lpush chan zero
(integer) 1
127.0.0.1:6379[10]> lrange chan 0 -1
1) "zero"
127.0.0.1:6379[10]> lrange chan 0 -1
1) "zero"
127.0.0.1:6379[10]> lpush chan l1 l2 l3
(integer) 4
127.0.0.1:6379[10]> rpush chan r1 r2 r3
(integer) 7
127.0.0.1:6379[10]> lrange chan 0 -1
1) "l3"
2) "l2"
3) "l1"
4) "zero"
5) "r1"
6) "r2"
7) "r3"

当数组存在时再添加: LPushX and RPushX

只有到目标数组 存在时LPushXRPushX 才会将元素加入到数组中。

LPUSHX key element [element ...]
RPUSHX key element [element ...]

分别 从左或从右 向数组中添加 至少一个 元素。

127.0.0.1:6379> lpush list_x "world"
(integer) 1
127.0.0.1:6379> LPUSHX list_x "hello"
(integer) 2
127.0.0.1:6379> LRANGE list_x 0 -1
1) "hello"
2) "world"
127.0.0.1:6379>
127.0.0.1:6379> LPUSHX lsit_no "hello"
(integer) 0
127.0.0.1:6379> LRANGE list_no 0 -1
(empty array)
127.0.0.1:6379>

遍历元素: LRANGE

遍历数据只有命令 LRange, 即只能从左侧开始,不能从右侧开始。

LRANGE key start stop

start/stop 表示了数据的下标位置。 0 表示第一个元素, -1 表示最后一个元素。

127.0.0.1:6379[10]> LRANGE chan 0 -1
1) "l3"
2) "l2"
3) "l1"
4) "zero"
5) "r1"
6) "r2"
7) "r3"
127.0.0.1:6379[10]> LRANGE chan 3 -3
1) "zero"
2) "r1"

取出元素: LPOPRPOP

与 push 相反, pop 是取出左右两边最外面的 N个 元素

LPOP key [count]

count 为可选参数, 默认值为 1

127.0.0.1:6379[10]> LPOP chan 2
1) "l3"
2) "l2"

127.0.0.1:6379[10]> RPOP chan
"r3"

127.0.0.1:6379[10]> LRANGE chan 0 -1
1) "l1"
2) "zero"
3) "r1"
4) "r2"

根据索引获取列表元素: LIndex

根据列表中元素的索引获取元素。

LINDEX key index

index 表示元素索引位置。 0 表示第一个元素, -1 表示最后一个元素。

127.0.0.1:6379[10]> LRANGE chan 0 -1
1) "l1"
2) "zero"
3) "r1"
4) "r2"
127.0.0.1:6379[10]> LINDEX chan 0
"l1"
127.0.0.1:6379[10]> LINDEX chan 2
"r1"
127.0.0.1:6379[10]> LINDEX chan -2
"r1"

列表长度: LLEN

返回列表元素个数

LLEN key

ex:

127.0.0.1:6379[10]> LLEN chan
(integer) 4

在列表中间插入元素: LINSERT

列表 所有两侧 push/pop 数据效率是最高的, 但 redis 也支持在列表中间添加元素。

LINSERT key BEFORE|AFTER pivot element

pivot

127.0.0.1:6379[10]> LRANGE chan 0 -1
1) "l1"
2) "zero"
3) "r1"
4) "r2"
127.0.0.1:6379[10]> LINSERT chan BEFORE zero insL1
(integer) 5
127.0.0.1:6379[10]> LINSERT chan AFTER zero insR1
(integer) 6
127.0.0.1:6379[10]> LRANGE chan 0 -1
1) "l1"
2) "insL1"
3) "zero"
4) "insR1"
5) "r1"
6) "r2"

删除元素: LREM

通过 LREM 可以删除列表中 指定数量特定元素

LREM key count element
  1. element 需要倍删除的元素。
  2. count 删除数量个数

    • count > 0 从左往右 计数。
    • count < 0 从右往左 计数。
    • count = 0 删除所有 符合的元素。
127.0.0.1:6379> RPUSH mylist hello
(integer) 1
127.0.0.1:6379> RPUSH mylist hello
(integer) 2
127.0.0.1:6379> RPUSH mylist foo
(integer) 3
127.0.0.1:6379> RPUSH mylist hello
(integer) 4
127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "hello"  # 被删
3) "foo"
4) "hello"  # 被删
127.0.0.1:6379> LREM mylist -2 hello
(integer) 2
127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "foo"

替换元素: LSET

使用 LSET 根据 下标 替换数组中的对应元素。

LSET key index element
  1. index 下标位置。 0 为第一元素; -1 为最后一个元素。
  2. element 新元素的值
127.0.0.1:6379> LRANGE mylist 0 -1
1) "foo"
2) "foo"
3) "hello"
4) "foo"

127.0.0.1:6379> LSET mylist 0 FOO
OK
127.0.0.1:6379> LSET mylist -1 __FOO__
OK
127.0.0.1:6379> LRANGE mylist 0 -1
1) "FOO"
2) "foo"
3) "hello"
4) "__FOO__"

元素转移: 右出左进 RpopLpush

将一个元素从 数组A右侧 取出, 并放入 数组B 的左侧

RPOPLPUSH source destination
  1. source 源数组
  2. destination 目标数组
127.0.0.1:6379> rpush list_A 1 2 3 4
(integer) 4
127.0.0.1:6379> rpush list_B a b c d
(integer) 4
127.0.0.1:6379> RPOPLPUSH list_A list_B
"4"
127.0.0.1:6379> LRANGE list_A 0 -1
1) "1"
2) "2"
3) "3"
127.0.0.1:6379> lrange list_B 0 -1
1) "4"
2) "a"
3) "b"
4) "c"
5) "d"

其他命令

更多 list 相关命令

https://redis.io/commands/#list

数据结构

  1. List 的数据结构为 快速链表 quickList
  2. 首先在列表 元素较少的情况下会使用一块连续的内存存储 ,这个结构是 ziplist,也即是 压缩列 。它将所有的元素紧挨着一起存储,分配的是一块连续的内存。
  3. 当数据量比较多的时候才会改成 quicklist 。 因为普通的链表需要的附加指针空间太大,会比较浪费空间。比如这个列表里存的只是 int 类型的数据,结构上还需要两个额外的指针prev和next。
  4. Redis 将链表和 ziplist 结合起来组成了 quicklist 。也就是将多个 ziplist 使用双向指针串起来使用。 这样既满足了快速的插入删除性能, 又不会出现太大的空间冗余。

20220311145251

相关文章
|
6月前
|
消息中间件 缓存 NoSQL
Redis各类数据结构详细介绍及其在Go语言Gin框架下实践应用
这只是利用Go语言和Gin框架与Redis交互最基础部分展示;根据具体业务需求可能需要更复杂查询、事务处理或订阅发布功能实现更多高级特性应用场景。
393 86
|
6月前
|
存储 消息中间件 NoSQL
【Redis】常用数据结构之List篇:从常用命令到典型使用场景
本文将系统探讨 Redis List 的核心特性、完整命令体系、底层存储实现以及典型实践场景,为读者构建从理论到应用的完整认知框架,助力开发者在实际业务中高效运用这一数据结构解决问题。
|
8月前
|
存储 NoSQL 定位技术
Redis数据类型面试给分情况
Redis常见数据类型包括:string、hash、list、set、zset(有序集合)。此外还包含高级结构如bitmap、hyperloglog、geo。不同场景可选用合适类型,如库存用string,对象存hash,列表用list,去重场景用set,排行用zset,签到用bitmap,统计访问量用hyperloglog,地理位置用geo。
337 5
|
8月前
|
NoSQL Java Redis
Redis基本数据类型及Spring Data Redis应用
Redis 是开源高性能键值对数据库,支持 String、Hash、List、Set、Sorted Set 等数据结构,适用于缓存、消息队列、排行榜等场景。具备高性能、原子操作及丰富功能,是分布式系统核心组件。
680 2
|
存储 缓存 NoSQL
解决Redis缓存数据类型丢失问题
解决Redis缓存数据类型丢失问题
547 85
|
12月前
|
人工智能 Java
Java 中数组Array和列表List的转换
本文介绍了数组与列表之间的相互转换方法,主要包括三部分:1)使用`Collections.addAll()`方法将数组转为列表,适用于引用类型,效率较高;2)通过`new ArrayList&lt;&gt;()`构造器结合`Arrays.asList()`实现类似功能;3)利用JDK8的`Stream`流式计算,支持基本数据类型数组的转换。此外,还详细讲解了列表转数组的方法,如借助`Stream`实现不同类型数组间的转换,并附带代码示例与执行结果,帮助读者深入理解两种数据结构的互转技巧。
852 1
Java 中数组Array和列表List的转换
|
12月前
|
NoSQL Redis
Redis的常用数据类型有哪些 ?
Redis 有 5 种基础数据结构,它们分别是:string(字符串)、list(列表)、hash(字典)、set(集 合) 和 zset(有序集合)
|
NoSQL 安全 Java
Redis6入门到实战------ 三、常用五大数据类型(字符串 String)
这篇文章深入探讨了Redis中的String数据类型,包括键操作的命令、String类型的命令使用,以及String在Redis中的内部数据结构实现。
Redis6入门到实战------ 三、常用五大数据类型(字符串 String)
|
存储 缓存 NoSQL
深入理解Redis数据类型String原理
本文深入探讨了Redis中String数据类型的实现原理和使用场景,基于Redis 5.0版本进行分析。
深入理解Redis数据类型String原理
|
缓存 NoSQL Redis
Redis深度解析:核心数据类型之string
Redis 数据类型包括String、Hash、List、Set和Sorted Set。对于String类型的主要操作, 此外,还有通用的Key操作。