Redis值数据类型——list
4.3 list
4.3.1 概述
- 存储内容
可存储有序的字符串列表;
- 常用操作
向列表两端添加元素、获取列表的某一个片段;
- 底层实现
基于双向链表(double linked list);
- 性能特性
- 向列表两端添加元素的时间复杂度为 O (1);
- 获取元素时,越接近列表两端的元素,访问速度越快;
- 极端场景验证:即便列表包含几千万个元素,获取其头部或尾部的 10 条记录仍能达到极快的速度。
4.3.2 命令
- 向列表两端增加元素
执行 lpush/rpush 时,Redis 会自动创建这个列表,并将元素插入。如果列表存在就会在已有列表上进行操作。向列表(key)的左侧(头部) 增加一个 / 多个元素。多个值按传入顺序依次从左侧插入。
lpush key value [value ...]向列表(key)的右侧(尾部) 增加一个 / 多个元素。
多个值按传入顺序依次从右侧插入。
rpush key value [value ...]
结果:3 → 2 → 1 → 4 → 5 → 6
- 从列表两端弹出元素
lpop key rpop keylpop命令从列表左边弹出一个元素,会分两步完成。第一步是将列表左边的元素从列表中移除,第二步是返回被移除的元素值。rpop同理。

- 获取列表中元素个数
llen key
4.获取列表片段
lrange key start stoplrange命令是列表类型最常用的命令之一,获取列表中的某一片段,将返回start、stop之间的所有元素(包含两端的元素),索引从0开始。索引可以是负数,如:“-1”代表最后边的一个元素。

- 删除列表中指定的值
lrem key count valuelrem命令会在列表里找值为value的元素,然后只删除其中的的前count个。根据count值的不同,该命令的执行方式会有所不同:
- 当count>0时, LREM会从列表左边开始删除。
- 当count<0时, LREM会从列表后边开始删除。
- 当count=0时, LREM删除所有值为value的元素。

- 获取/设置指定索引的元素值
LINDEX key index LSET key index value
- 只保留列表指定片段
只保留列表指定片段,指定范围和LRANGE一致
LTRIM key start stop
8.向列表中插入元素
LINSERT key BEFORE|AFTER pivot value该命令首先会在列表中从左到右查找值为pivot的元素,然后根据第二个参数是BEFORE还是AFTER来决定将value插入到该元素的前面还是后面。

- 将元素从一个列表转移到另一个列表中
先从 source 列表的右侧(尾部) 弹出一个元素。再把这个元素插入到 destination 列表的左侧(头部)。返回被移动的元素。
RPOPLPUSH source destination
4.3.3 方法
- List 类型核心操作
功能 | StringRedisTemplate 方法 | 对应 Redis 命令 | 代码中的作用 |
右侧(尾部)添加元素 | opsForList().rightPush(key, value) | rpush | 向列表尾部追加单个元素 |
左侧(头部)添加元素 | opsForList().leftPush(key, value) | lpush | 向列表头部插入单个元素(最新元素在头部,适合评论 / 消息场景) |
获取指定范围元素 | opsForList().range(key, start, end) | lrange | 获取列表中 start 到 end 下标元素( 0,-1 表示所有元素, 0,3 表示前 4 个) |
获取列表长度 | opsForList().size(key) | llen | 返回列表的元素总个数 |
修改指定下标值 | opsForList().set(key, index, value) | lset | 更新列表中指定下标位置的元素值 |
获取指定下标值 | opsForList().index(key, index) | lindex | 查询列表中指定下标位置的元素值 |
删除指定数量的目标值 | opsForList().remove(key, count, value) | lrem | 按方向删除 count 个值为 value 的元素( count>0 从左删, count=0 删所有) |
截取列表保留指定区间 | opsForList().trim(key, start, end) | ltrim | 仅保留列表中 start 到 end 下标元素,删除区间外所有元素 |
左侧(头部)出栈 | opsForList().leftPop(key) | lpop | 从列表头部弹出元素(元素从列表中移除,返回弹出值) |
- List 关联的通用操作
功能 | StringRedisTemplate 方法 | 对应 Redis 命令 | 代码中的作用 |
删除整个列表 | delete(key) | del | 直接删除列表键,清空列表所有元素 |
清空当前数据库 | getConnectionFactory().getConnection().flushDb() | flushdb | 清空当前 Redis 库的所有键(含 List、Hash、String 等所有类型) |
- 结论
- List 类型操作的核心套路:stringRedisTemplate.opsForList().xxx();
- 方向相关:rightPush/leftPush 对应 “尾加 / 头加”,leftPop 对应 “头出”,符合 Redis List 双向链表特性;
- 范围操作:range/trim 的下标规则和 Redis 一致(从 0 开始,-1 表示最后一个元素);
- 删除逻辑:remove 仅删除 “值匹配” 的元素,count 控制删除数量和方向,而非删除列表下标元素。
- 代码
package com.qcby.springbootredis; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.StringRedisTemplate; import java.util.List; @SpringBootTest public class ListTest { // 注入 SpringBoot 自带的 StringRedisTemplate(替代 Jedis,自动管理连接池) @Autowired private StringRedisTemplate stringRedisTemplate; /** * List 类型核心操作(对应原 Jedis 的 testList 方法) */ @Test public void testList() { System.out.println("==List=="); try { // ========== 1. 移除指定 list 的所有内容========== stringRedisTemplate.delete("messages"); // ========== 2. 向 list 右侧(尾部)添加元素 ========== stringRedisTemplate.opsForList().rightPush("messages", "Hello how are you?"); stringRedisTemplate.opsForList().rightPush("messages", "Fine thanks. I'm having fun with redis."); stringRedisTemplate.opsForList().rightPush("messages", "I should look into this NOSQL thing ASAP"); // ========== 3. 获取 list 所有元素 ========== // 0 = 起始下标,-1 = 结束下标(表示所有元素) List<String> values = stringRedisTemplate.opsForList().range("messages", 0, -1); System.out.println("messages 所有元素:" + values); // ========== 4. 清空当前数据库 ========== stringRedisTemplate.getConnectionFactory().getConnection().flushDb(); System.out.println("清空当前数据库成功"); // ========== 5. 向 list 左侧(头部)添加元素 ========== stringRedisTemplate.opsForList().leftPush("lists", "vector"); stringRedisTemplate.opsForList().leftPush("lists", "ArrayList"); stringRedisTemplate.opsForList().leftPush("lists", "LinkedList"); // ========== 6. 获取 list 长度 ========== Long listSize = stringRedisTemplate.opsForList().size("lists"); System.out.println("lists 长度:" + listSize); // ========== 7. 获取 list 指定范围元素 ========== List<String> rangeValues = stringRedisTemplate.opsForList().range("lists", 0, 2); System.out.println("lists 0-2 范围元素:" + rangeValues); // ========== 8. 修改 list 指定下标的值 ========== stringRedisTemplate.opsForList().set("lists", 0, "hello list!"); System.out.println("修改 lists 下标 0 的值为 hello list! 成功"); // ========== 9. 获取 list 指定下标的值(对应 jedis.lindex("lists", 1)) ========== String indexValue = stringRedisTemplate.opsForList().index("lists", 1); System.out.println("lists 下标 1 的值:" + indexValue); // ========== 10. 删除 list 中指定数量的目标值 ========== // 参数:key、删除数量(count)、目标值(value)→ 从左删 1 个 "vector" Long removeCount = stringRedisTemplate.opsForList().remove("lists", 1, "vector"); System.out.println("删除 lists 中 vector 的数量:" + removeCount); // ========== 11. 截取 list 保留指定区间,删除区间以外的数据 ========== stringRedisTemplate.opsForList().trim("lists", 0, 1); System.out.println("截取 lists 0-1 区间,删除其他元素成功"); // ========== 12. list 左侧(头部)出栈 ========== String leftPopValue = stringRedisTemplate.opsForList().leftPop("lists"); System.out.println("lists 左侧出栈元素:" + leftPopValue); // ========== 13. 再次获取 list 所有元素,查看最终结果 ========== List<String> finalValues = stringRedisTemplate.opsForList().range("lists", 0, -1); System.out.println("lists 最终剩余元素:" + finalValues); } catch (Exception e) { e.printStackTrace(); } } /** * 商品评论列表业务场景实现 */ @Test public void testGoodsCommentList() { // 1. 定义商品评论列表 key(商品 1001 的评论) String goodsCommentKey = "items:comment:1001"; // 2. 模拟用户发布商品评论(将评论转为 JSON 字符串,左侧插入List → 最新评论在头部) String comment1 = "{\"id\":1,\"name\":\"商品不错,很好!!\",\"date\":1430295077289}"; String comment2 = "{\"id\":2,\"name\":\"质量很好,性价比高\",\"date\":1430295177289}"; stringRedisTemplate.opsForList().leftPush(goodsCommentKey, comment1); stringRedisTemplate.opsForList().leftPush(goodsCommentKey, comment2); // 3. 模拟页面查询评论列表(从 Redis 中取出所有评论 JSON 数据) List<String> goodsComments = stringRedisTemplate.opsForList().range(goodsCommentKey, 0, -1); // 4. 打印展示评论列表(实际开发中可反序列化为对象,返回给前端页面) System.out.println("商品 1001 评论列表:"); for (String comment : goodsComments) { System.out.println(comment); } } }
