redis-05 五大基本类型之List

发布时间:2022-07-03 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了redis-05 五大基本类型之List脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

redis-05 五大基本类型之List

目录
  • redis-05 五大基本类型之List
    • 概述
    • 命令
      • 增、删
      • 截取链表
      • 链表倒腾
      • 按址操作
        • 按址改值
        • trim 操作
      • 按值操作
        • 链表插入
    • 实践
      • 存储文章 ID 列表
      • 存储文章评论

概述

Redis 中的 List 可以存储一个有序的字符串(存储的内容只能是字符串!)列表,由于可以对列表同时进行操作,这使得它同时具备了 stack 和 queue 的特性。

Redis 中的列表类型是通过双向链表实现的,所以查和改两端快,中间慢。

Redis 的集合数据类型都不支持嵌套,列表里面不能存储列表等其它元素,集合里面不能存储列表而只能存储字符串。

命令

增、删

  • lpush
    • 在链表左侧添加一个元素
  • rpop
    • 弹出链表右侧的一个元素
@test
public void pushAndPop() {
    long len = j.lpush("numbers", "1", "2", "3");
    assertEquals(3L, len);
    // 3, 2, 1

    len = j.rpush("numbers", "4", "5", "6");
    assertEquals(6L, len);
    // 3, 2, 1, 4, 5, 6

    String number = j.lpop("numbers");
    assertEquals("3", number);

    number = j.rpop("numbers");
    assertEquals("6", number);
}

截取链表

  • llen
    • 获取链表长度
  • lrange
  • lrem
    • 移出指定个数的指定值的链表元素
@Test
public void subListAndLen() {
    long len = j.lpush("numbers", "1", "2", "3");
    assertEquals(3L, len);
    // 3, 2, 1

    len = j.rpush("numbers", "4", "5", "6");
    assertEquals(6L, len);
    // 3, 2, 1, 4, 5, 6

    len = j.llen("numbers");
    assertEquals(6L, len);

    List<String> numbers = j.lrange("numbers", 1L, 4L);
    assertEquals(4, numbers.size());
    assertEquals("2", numbers.get(0));

    // 顺序永远只能是从左向右
    List<String> numbers1 = j.lrange("numbers", -3L, -1L);
    // 3, 5, 6
    assertEquals("4", numbers1.get(0));

    // 当第二个参数 count > 0 时,删除所有匹配元素,负数和正数则会分别
    // 从左到右或者从右到左删除指定个匹配的元素
    long effected = j.lrem("numbers", 0, "1");
    assertEquals(1L, effected);
}

链表倒腾

  • rpoplpush
    • 顾名思义
    • 弹一个、加一个
@Test
public void listElementtransfer() {
    long len = j.lpush("numbers", "1", "2", "3");
    assertEquals(3L, len);
    // 3, 2, 1

    len = j.rpush("numbers", "4", "5", "6");
    assertEquals(6L, len);
    // 3, 2, 1, 4, 5, 6

    String number = j.rpoplpush("numbers", "newNumbers");
    assertEquals("6", number);

    number = j.rpoplpush("numbers", "newNumbers");
    assertEquals("5", number);

    List<String> newNumbers = j.lrange("newNumbers", 0, -1);
    assertNotNull(newNumbers);
    assertEquals(2, newNumbers.size());
    assertEquals("5", newNumbers.get(0));
    assertEquals("6", newNumbers.get(1));

    // You can also use this command to move the last element to the front of list in the same list
}

按址操作

按址改值

  • lindex
    • 获取指定下标的元素
    • 下标越界返回 nil(null)
  • lset
    • 设置指定下标的元素的值
    • 下标越界抛出异常
@Test
public void getAndSetListValueByIndex() {
    long len = j.lpush("numbers", "1", "2", "3");
    assertEquals(3L, len);
    // 3, 2, 1

    len = j.rpush("numbers", "4", "5", "6");
    assertEquals(6L, len);
    // 3, 2, 1, 4, 5, 6

    String number_2 = j.lindex("numbers", 1L);
    assertEquals("2", number_2);

    // 下标越界会返回 null
    String number_7 = j.lindex("numbers", 7L);
    assertNull(number_7);

    String status = j.lset("numbers", 4L, "55");
    assertEquals("OK", status);

    String number_4 = j.lindex("numbers", 4L);
    assertEquals("55", number_4);

    try {
        number_7 = j.lset("numbers", 7L, "77");
        assertNull(number_7);
    } catch (JedisDataException e) {
        System.err.PRintln(e);
    }
}
// 执行结果
// redis.clients.jedis.exceptions.JedisDataException: ERR index out of range

trim 操作

  • trim
    • 截取制定位置的链表元素
    • 原链表发生改变
@Test
public void lTrim() {
    long len = j.lpush("numbers", "1", "2", "3");
    assertEquals(3L, len);
    // 3, 2, 1

    len = j.rpush("numbers", "4", "5", "6");
    assertEquals(6L, len);
    // 3, 2, 1, 4, 5, 6

    String status = j.ltrim("numbers", 1L, 4L);
    // 2, 1, 4, 5
    assertEquals("OK", status);

    List<String> numbers = j.lrange("numbers", 0, -1);
    assertNotNull(numbers);
    assertEquals(4, numbers.size());
    assertEquals("2", numbers.get(0));
    assertEquals("1", numbers.get(1));
    assertEquals("4", numbers.get(2));
    assertEquals("5", numbers.get(3));
}

按值操作

链表插入

  • linsert
    • 指定值的指定位置插入热定值
@Test
public void insertIntoList() {
    long len = j.lpush("numbers", "1", "2", "3");
    assertEquals(3L, len);
    // 3, 2, 1

    len = j.rpush("numbers", "4", "5", "6");
    assertEquals(6L, len);
    // 3, 2, 1, 4, 5, 6

    len = j.linsert("numbers", ListPosITion.AFTER, "2", "8");
    assertEquals(7L, len);
    // 3, 2, 8, 1, 4, 5, 6

    len = j.linsert("numbers", ListPosition.BEFORE, "1", "7");
    assertEquals(8L, len);

    String number_3 = j.lindex("numbers", 3);
    assertEquals("7", number_3);
}

实践

存储文章 ID 列表

我们使用一个 posts:list 来记录文章 ID 列表。这样一来分页操作就变得非常简单了(在这里不做演示)。

存储文章评论

由于评论一般不具备可修改性,所以能直接将评论对象序列化后存储在对应的文章评论列表中。

脚本宝典总结

以上是脚本宝典为你收集整理的redis-05 五大基本类型之List全部内容,希望文章能够帮你解决redis-05 五大基本类型之List所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。