Redis值数据类型——list

4.3 list

4.3.1 概述

  1. 存储内容
    可存储有序的字符串列表;
  2. 常用操作
    向列表两端添加元素、获取列表的某一个片段;
  3. 底层实现
    基于双向链表(double linked list);
  4. 性能特性
  • 向列表两端添加元素的时间复杂度为 O (1);
  • 获取元素时,越接近列表两端的元素,访问速度越快;
  • 极端场景验证:即便列表包含几千万个元素,获取其头部或尾部的 10 条记录仍能达到极快的速度。

4.3.2 命令

  1. 向列表两端增加元素
    执行 lpush/rpush 时,Redis 会自动创建这个列表,并将元素插入。如果列表存在就会在已有列表上进行操作。
    向列表(key)的左侧(头部) 增加一个 / 多个元素。
    多个值按传入顺序依次从左侧插入。

    lpush key value [value ...]

向列表(key)的右侧(尾部) 增加一个 / 多个元素。

多个值按传入顺序依次从右侧插入。

复制代码
rpush key value [value ...]


结果:3 → 2 → 1 → 4 → 5 → 6

  1. 从列表两端弹出元素

    lpop key
    rpop key

lpop命令从列表左边弹出一个元素,会分两步完成。第一步是将列表左边的元素从列表中移除,第二步是返回被移除的元素值。rpop同理。

  1. 获取列表中元素个数

    llen key

4.获取列表片段

复制代码
lrange key start stop

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

  1. 删除列表中指定的值

    lrem key count value

lrem命令会在列表里找值为value的元素,然后只删除其中的的前count个。
根据count值的不同,该命令的执行方式会有所不同:

  • 当count>0时, LREM会从列表左边开始删除。
  • 当count<0时, LREM会从列表后边开始删除。
  • 当count=0时, LREM删除所有值为value的元素。
  1. 获取/设置指定索引的元素值

    LINDEX key index
    LSET key index value

  1. 只保留列表指定片段
    只保留列表指定片段,指定范围和LRANGE一致

    LTRIM key start stop

8.向列表中插入元素

复制代码
LINSERT key BEFORE|AFTER pivot value

该命令首先会在列表中从左到右查找值为pivot的元素,然后根据第二个参数是BEFORE还是AFTER来决定将value插入到该元素的前面还是后面。

  1. 将元素从一个列表转移到另一个列表中
    先从 source 列表的右侧(尾部) 弹出一个元素。
    再把这个元素插入到 destination 列表的左侧(头部)。
    返回被移动的元素。

    RPOPLPUSH source destination

4.3.3 方法

  1. 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 | 从列表头部弹出元素(元素从列表中移除,返回弹出值) |

  1. List 关联的通用操作

|---------|--------------------------------------------------|-------------|--------------------------------------------|
| 功能 | StringRedisTemplate 方法 | 对应 Redis 命令 | 代码中的作用 |
| 删除整个列表 | delete(key) | del | 直接删除列表键,清空列表所有元素 |
| 清空当前数据库 | getConnectionFactory().getConnection().flushDb() | flushdb | 清空当前 Redis 库的所有键(含 List、Hash、String 等所有类型) |

  1. 结论
  • List 类型操作的核心套路:stringRedisTemplate.opsForList().xxx();
  • 方向相关:rightPush/leftPush 对应 "尾加 / 头加",leftPop 对应 "头出",符合 Redis List 双向链表特性;
  • 范围操作:range/trim 的下标规则和 Redis 一致(从 0 开始,-1 表示最后一个元素);
  • 删除逻辑:remove 仅删除 "值匹配" 的元素,count 控制删除数量和方向,而非删除列表下标元素。
  1. 代码

    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);
      }
      }

    }

相关推荐
尽兴-2 小时前
拨开迷雾:深入理解 Redis 7 的线程模型
数据库·redis·缓存·redis7·线程模型
**蓝桉**2 小时前
一键恢复 Redis 运行与 Grafana 监控(免修改 systemd 配置)
redis·bootstrap·grafana
2401_857865232 小时前
使用XGBoost赢得Kaggle比赛
jvm·数据库·python
暮冬-  Gentle°2 小时前
使用Python进行网络设备自动配置
jvm·数据库·python
czlczl200209252 小时前
Redis五种数据类型底层
数据库·redis·缓存
轩情吖2 小时前
MySQL内置函数
android·数据库·c++·后端·mysql·开发·函数
ID_云泽2 小时前
MySQL 备份工具分享(三):定时全量备份
数据库·mysql·数据备份
m0_743297422 小时前
将Python Web应用部署到服务器(Docker + Nginx)
jvm·数据库·python
可夫小子2 小时前
OpenClaw进阶-Macmini远程访问设置
数据库