redis使用rightPushAll保存List,List的size为1

2023-11-15

redis使用rightPushAll保存List,List的size为1

问题描述

使用RedisTemplate保存List,期望是直接将Java的List直接转换redis的list。但是rightPushAll执行之后,却将整个list作为一个元素存到redis里面了。代码demo如下

@Controller
public class RedisTest {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @ResponseBody
    @GetMapping("/test")
    public Long test(){
     	String key = "test";
        redisTemplate.delete(key);
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("1");
        arrayList.add("2");
        arrayList.add("3");
        Long size = redisTemplate.opsForList().rightPushAll(key, arrayList); 
        //output 1
        System.out.println(redisTemplate.opsForList().size(key));
        List<Object> range = redisTemplate.opsForList().range(key, 0, -1);
        //output [[1, 2, 3]]
        System.out.println(range);
        return size;
    }
}

执行想要的结果是size=3,list=[1, 2, 3]。但是执行的结果却是size=1,list=[[1, 2, 3]]

问题定位

rightPushAll有两个重载方法:第一个方法values形参的接收参数是一个可变长度的泛型参数列表,第二个方法values形参的接收参数是泛型的Collection。

	/*
	 * (non-Javadoc)
	 * @see org.springframework.data.redis.core.ListOperations#rightPushAll(java.lang.Object, java.lang.Object[])
	 */
	@Override
	public Long rightPushAll(K key, V... values) {

		byte[] rawKey = rawKey(key);
		byte[][] rawValues = rawValues(values);
		return execute(connection -> connection.rPush(rawKey, rawValues));
	}

	/*
	 * (non-Javadoc)
	 * @see org.springframework.data.redis.core.ListOperations#rightPushAll(java.lang.Object, java.util.Collection)
	 */
	@Override
	public Long rightPushAll(K key, Collection<V> values) {

		byte[] rawKey = rawKey(key);
		byte[][] rawValues = rawValues(values);
		return execute(connection -> connection.rPush(rawKey, rawValues));
	}

因为调用方法实参values是一个List,从语法上来说,两个重载方法是都可以调到的。因为重载是Java编译时的多态性,那么编译器编译时会调用哪个方法呢?实参ArrayList实现了Collection接口,所以误认为会走rightPushAll(K key, Collection<V> values)方法,但是Collection是带泛型的,RedisTemplate<String, Object>的value指定的泛型是Object,存值时保存的ArrayList指定的泛型却是String,虽然String继承了Object,但是编辑器编辑时还是会优先选择调用rightPushAll(K key, V... values)进行编译。可以通过打断点或者查看字节码文件验证,确实调用的是rightPushAll(K key, V... values)方法。生成的字节码文件

解决方案:

RedisTemplate<K, V> 指定的value值和传入的value值的泛型类型保持一致。比如上文中的例子,只需将 private RedisTemplate<String, Object> redisTemplate;改为private RedisTemplate<String, String> redisTemplate;或者 RedisTemplate不变将ArrayList<String> arrayList = new ArrayList<>();改为ArrayList<Object> arrayList = new ArrayList<>();

问题疑惑

为什么编译器会优先走rightPushAll(K key, V... values)方法?重载的顺序到底是怎么样的?特别是泛型或者可变参数列表的形参,编译的原理是怎样的?欢迎有答案的小伙伴给我留言或者粘贴相关资料链接

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

redis使用rightPushAll保存List,List的size为1 的相关文章

随机推荐

  • TP6关于hasOne的用法

    TP6关于hasOne的用法 实际操作中看如下案例 文章分类表 CREATE TABLE case category id bigint 20 unsigned NOT NULL AUTO INCREMENT COMMENT 主键id na
  • GO语言网络编程(并发编程)Channel

    GO语言网络编程 并发编程 Channel 1 Channel 1 1 1 Channel 单纯地将函数并发执行是没有意义的 函数与函数间需要交换数据才能体现并发执行函数的意义 虽然可以使用共享内存进行数据交换 但是共享内存在不同的goro
  • hmcl启动器安装游戏版本失败_有关HMCL的个人粗糙介绍

    简单介绍关于HMCL Hello Minecraft Launcher 受欢迎的 Minecraft 启动器的使用 github https github com huanghongxun HMCL releases 1 使用前的一些调试
  • 「问题记录|VirtualBox」OSX系统启动就异常退出的问题

    背景说明 需要一个OSX系统进行软件打包 原本想在docker中进行 奈何电脑配置不够格 所以还是回归VirtualBox的怀抱 这里记录一个小操作 问题描述 虚拟机启动后加载完毕后闪退 快到甚至有可能没看到窗口 然后就看到侧边列表的虚拟机
  • Python USB通讯

    1 下载libusb 地址 Releases libusb libusb GitHub 下载7z压缩包文件到本地 解压后将32位版本的dll文件拷贝到C Windows System32 64位的dll文件拷贝到C Windows SysW
  • pytorch中的二分类及多分类交叉熵损失函数

    本文主要记录一下pytorch里面的二分类及多分类交叉熵损失函数的使用 import torch import torch nn as nn import torch nn functional as F torch manual seed
  • bin目录下存放的是什么文件?

    bin文件夹通常里面都是什么文件 经常使用电脑系统安装程序的朋友可能会发现 很多软件在安装后都会产生一个bin文件夹 那么bin文件夹是什么 里面大多放着什么文件呢 下面我们来学习一下 避免一些错误的认知导致程序损坏等误操作 软件的安装后文
  • activiti5.17.0流程图及节点显示

    引用 activiti流程图上获取各节点的信息获取 这篇文章写得很好 揭示了图片点击出现信息的方法 于是我也做了 只不过有些改动 可能是activiti的版本不同的原因 jsp页面 通过流程实例id进行操作
  • 【从嵌入式视角学习香山处理器】四、Chisel语言基础

    文章目录 一 前言 二 Linux上对scala工程的操作 1 helloworld执行命令 2 有多个工程目录时 需要切换工程 3 编译报错 4 给vscode的scala插件设置JAVA HOME路径 三 ch4 基本组成部分 ch4
  • 第二章实验1

    周末没事正好练习下 前边 r原以为是只查看cpu寄存器内容 原来还有修改的意思 只用r即查询 用r 寄存器 则是修改该寄存器 不只是可以修改ax 可以修改其他寄存器 d 段地址 偏移地址 查看内存内容 最左边是每行的起始地址 中间是从指定内
  • dev-tool安装方法(手动安装版)

    记录一下vue调试神器dev tool的安装过程 由于是在公司内网 也不方便挂梯子 所以手动安装 下载源码在本地编译 再添加扩展程序的方式安装 过程如下 一 dev tool源码获取 git地址 https github com vuejs
  • Git分支管理策略

    原文地址 http www ruanyifeng com blog 2012 07 git html 如果你严肃对待编程 就必定会使用 版本管理系统 Version Control System 眼下最流行的 版本管理系统 非Git莫属 相
  • 通过post请求下载接口,接口返回流数据,前端处理下载或展示出错信息

    需求描述 1 使用post请求 参数放在请求体内 所以不能用get请求 2 后端返回流 二进制数据 前端自己处理下载 3 如果后端出错 后端返回json数据 前端处理 展示错误内容 实现 1 后端需要设置 response Content
  • 攻防世界--web--新手区

    攻防世界 web 新手区 0x01 view source 题目描述 X老师让小宁同学查看一个网页的源代码 但小宁同学发现鼠标右键好像不管用了 解题思路 进去之后显示FLAG is not here 然后就按F12查看Elements选项
  • 计算机网络---应用层概述

    一 应用层概述 基本定义 应用层 Application layer 是OSI模型的第七层 应用层直接和应用程序接口并提供常见的网络应用服务 应用层也向表示层发出请求 应用层是开放系统的最高层 是直接为应用进程提供服务的 其作用是在实现多个
  • TVM Relay softmax算子调度分析

    https github com apache tvm pull 8909 files 计算 调度分离 TOPI中的算子分为其算子的定义和算子的schedule两部分 算子的定义是唯一的 而对于不同的后端 x86 cuda等 schedul
  • 论文笔记:A Time Series is Worth 64 Words: Long-term Forecasting with Transformers

    ICLR 2023 比较简单 就不分intro model这些了 1 核心思想1 patching 给定每个时间段的长度 划分的stride 将时间序列分成若干个时间段 时间段之间可以有重叠 也可以没有 每一个时间段视为一个token 1
  • B - Can you solve this equation?(简单二分)

    Can you solve this equation Time limit 1000 ms Memory limit 32768 kB OS Windows Problem Description Now given the equati
  • C语言【二分查找】详解

    提示 文章写完后 目录可以自动生成 如何生成可参考右边的帮助文档 二分 文章目录 前言 一 二分查找 的步骤 二 二分查找 的注意事项 三 举例详解 二分查找 前言 一 二分查找 步骤 二 二分查找 的注意事项 三 举例详细讲解 二分查找
  • redis使用rightPushAll保存List,List的size为1

    redis使用rightPushAll保存List List的size为1 问题描述 问题定位 解决方案 问题疑惑 问题描述 使用RedisTemplate保存List 期望是直接将Java的List直接转换redis的list 但是rig