Redis值数据类型——list

4.3 list

4.3.1 概述

  1. 存储内容
可存储有序的字符串列表;
  1. 常用操作
向列表两端添加元素、获取列表的某一个片段;
  1. 底层实现
基于双向链表(double linked list);
  1. 性能特性
  • 向列表两端添加元素的时间复杂度为 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);
    }
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值