如何实现Redis缓存中泛型集合与JSON字符串的互转示例?

2026-05-24 10:271阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1551个文字,预计阅读时间需要7分钟。

如何实现Redis缓存中泛型集合与JSON字符串的互转示例?

难点是如何将泛型类型如ArrayList和Object转换为JSON字符串,并存储到Redis缓存中。以下是简化后的代码:

java// 将ArrayList类型的数据转换为JSON字符串并存储到Redis缓存ArrayList listProfit=new ArrayList();// 假设listProfit已经被填充了数据

// 将ArrayList转换为JSON字符串String listProfitPctJsonStr=JSON.toJSONString(listProfit);

// 存储到Redis缓存redisTemplate.opsForValue().set(listProfit, listProfitPctJsonStr);

难点是泛型如何转换

一、arrayList<Map<String, Object>>转化json字符串,存入redis缓存

ArrayList<Map<String, Object>> listProfit //将ArrayList<Map<String, Object>>类型数据转换成json字符串 String listProfitPctJsonStr = JSON.toJSONString(listProfit); //然后将json字符串存入redis缓存,唯一key value JedisUtils.setex("listProfit", 600,listProfitPctJsonStr);

二、json字符串转回ArrayList<Map<String, Object>>(难点)

List<Map<String, Object>> listProfit=null; //先从redis里面去查询数据,看是否能获取到对应json字符串 String jsonStrLp=JedisUtils.get("listProfit"); //如果能获取则说明缓存中有数据 if(!StringUtils.isBlank(jsonStrLp)){ //目的是为了泛型的转换 listProfit=new ArrayList<Map<String,Object>>(); //先把从redis缓存中取出来的json字符串转为List<Map>集合 List<Map> mapList=JSON.parseArray(jsonStrLp, Map.class); //然后循环遍历这个List集合,得出的结果为Map,然后再强转为Map<String,Object>, 再循环 把 Map<String,Object>添加到List集合中,搞定!!! for (Map map : mapList) { Map<String,Object> sObj=(Map<String,Object>)map; listProfit.add(sObj); }

补充知识:Java的List和Json转换以及StringRedisTemplate往redis存泛型对象

List转Json

List<User> user= new ArrayList();

String str = JSON.toJSONString(user);

Json 转List方法一

List<User> user= JSON.parseArray(json,User.class);

如果是泛型方法需要使用TypeReference

Json 转List 方法二

String json = "[{}]";

List<user> user= JSON.parseObject(json,new TypeReference<List<User>>(){});

泛型T

Json 转List方法三

List<T> students = JSON.parseObject(listCache,new TypeReference<List<T>>(){});

综合例子:Springboot环境下利用StringRedisTemplate往redis存泛型对象

一开始要注入下StringRedisTemplate

@Autowired

private StringRedisTemplate redisTemplate;

Redis获取值不存在就从数据库取出来json化存缓存,存在则直接反序列化json为List

List<T> list; String listCache=redisTemplate.opsForValue().get(key); if(listCache!=null){ list = JSON.parseObject(listCache,new TypeReference<List<T>>(){}); } else { list = userService.getAllList(); redisTemplate.opsForValue().set(key, JSON.toJSONString(list), 60 * 1, TimeUnit.SECONDS); }

附录:TypeReference源码

package com.alibaba.fastjson; import java.lang.reflect.GenericArrayType; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import com.alibaba.fastjson.util.ParameterizedTypeImpl; import com.alibaba.fastjson.util.TypeUtils; /** * Represents a generic type {@code T}. Java doesn't yet provide a way to * represent generic types, so this class does. Forces clients to create a * subclass of this class which enables retrieval the type information even at * runtime. * * <p>For example, to create a type literal for {@code List<String>}, you can * create an empty anonymous inner class: * * <pre> * TypeReference&lt;List&lt;String&gt;&gt; list = new TypeReference&lt;List&lt;String&gt;&gt;() {}; * </pre> * This syntax cannot be used to create type literals that have wildcard * parameters, such as {@code Class<?>} or {@code List<? extends CharSequence>}. */ public class TypeReference<T> { static ConcurrentMap<Type, Type> classTypeCache = new ConcurrentHashMap<Type, Type>(16, 0.75f, 1); protected final Type type; /** * Constructs a new type literal. Derives represented class from type * parameter. * * <p>Clients create an empty anonymous subclass. Doing so embeds the type * parameter in the anonymous class's type hierarchy so we can reconstitute it * at runtime despite erasure. */ protected TypeReference(){ Type superClass = getClass().getGenericSuperclass(); Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0]; Type cachedType = classTypeCache.get(type); if (cachedType == null) { classTypeCache.putIfAbsent(type, type); cachedType = classTypeCache.get(type); } this.type = cachedType; } /** * @since 1.2.9 * @param actualTypeArguments */ protected TypeReference(Type... actualTypeArguments){ Class<?> thisClass = this.getClass(); Type superClass = thisClass.getGenericSuperclass(); ParameterizedType argType = (ParameterizedType) ((ParameterizedType) superClass).getActualTypeArguments()[0]; Type rawType = argType.getRawType(); Type[] argTypes = argType.getActualTypeArguments(); int actualIndex = 0; for (int i = 0; i < argTypes.length; ++i) { if (argTypes[i] instanceof TypeVariable && actualIndex < actualTypeArguments.length) { argTypes[i] = actualTypeArguments[actualIndex++]; } // fix for openjdk and android env if (argTypes[i] instanceof GenericArrayType) { argTypes[i] = TypeUtils.checkPrimitiveArray( (GenericArrayType) argTypes[i]); } // 如果有多层泛型且该泛型已经注明实现的情况下,判断该泛型下一层是否还有泛型 if(argTypes[i] instanceof ParameterizedType) { argTypes[i] = handlerParameterizedType((ParameterizedType) argTypes[i], actualTypeArguments, actualIndex); } } Type key = new ParameterizedTypeImpl(argTypes, thisClass, rawType); Type cachedType = classTypeCache.get(key); if (cachedType == null) { classTypeCache.putIfAbsent(key, key); cachedType = classTypeCache.get(key); } type = cachedType; } private Type handlerParameterizedType(ParameterizedType type, Type[] actualTypeArguments, int actualIndex) { Class<?> thisClass = this.getClass(); Type rawType = type.getRawType(); Type[] argTypes = type.getActualTypeArguments(); for(int i = 0; i < argTypes.length; ++i) { if (argTypes[i] instanceof TypeVariable && actualIndex < actualTypeArguments.length) { argTypes[i] = actualTypeArguments[actualIndex++]; } // fix for openjdk and android env if (argTypes[i] instanceof GenericArrayType) { argTypes[i] = TypeUtils.checkPrimitiveArray( (GenericArrayType) argTypes[i]); } // 如果有多层泛型且该泛型已经注明实现的情况下,判断该泛型下一层是否还有泛型 if(argTypes[i] instanceof ParameterizedType) { return handlerParameterizedType((ParameterizedType) argTypes[i], actualTypeArguments, actualIndex); } } Type key = new ParameterizedTypeImpl(argTypes, thisClass, rawType); return key; } /** * Gets underlying {@code Type} instance. */ public Type getType() { return type; } public final static Type LIST_STRING = new TypeReference<List<String>>() {}.getType(); }

TypeReference的存在是因为java中子类可以获取到父类泛型的真实类型。

其中核心的方法是:getActualTypeArguments,它可以得到父类的反省类型

ParameterizedType是一个记录类型泛型的接口, 继承自Type,一共三方法:

Type[] getActualTypeArguments(); //返回泛型类型数组 Type getRawType(); //返回原始类型Type Type getOwnerType(); //返回 Type 对象,表示此类型是其成员之一的类型。

Map<String, Integer> intMap = new HashMap<>(); System.out.println("getSuperclass:" + intMap.getClass().getSuperclass()); System.out.println("getGenericSuperclass:" + intMap.getClass().getGenericSuperclass()); Type type = intMap.getClass().getGenericSuperclass(); if (type instanceof ParameterizedType) { ParameterizedType p = (ParameterizedType)type; for (Type t : p.getActualTypeArguments()) { System.out.println("getActualTypeArguments>>>"+t); } }

如何实现Redis缓存中泛型集合与JSON字符串的互转示例?

扩展阅读Java如何获得泛型类的真实类型:

package com.paopaoedu.springboot.demo; import com.paopaoedu.springboot.bean.User; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; public class BaseDao<T>{ private Class<T> clazz; // 使用反射技术得到T的真实类型 public Class getRealType(){ Class c=this.getClass(); //getSuperclass()获得该类的父类 System.out.println("getSuperclass >>>"+c.getSuperclass()); //getGenericSuperclass()获得带有泛型的父类 System.out.println("getGenericSuperclass >>>"+c.getGenericSuperclass()); //Type是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。 Type type=c.getGenericSuperclass(); System.out.println("Type >>>"+type); //ParameterizedType参数化类型,即泛型 // 获取当前new的对象的泛型的父类类型 ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); // 获取第一个类型参数的真实类型 this.clazz = (Class<T>) pt.getActualTypeArguments()[0]; c=(Class) pt.getActualTypeArguments()[0]; System.out.println(c); return clazz; } } class userdemo extends BaseDao<User>{ public static void main(String[] args) { userdemo classB = new userdemo(); Class realType = classB.getRealType(); System.out.println(realType.getName()); } }

以上这篇Redis缓存,泛型集合与json字符串的相互转换实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持易盾网络。

标签:相互

本文共计1551个文字,预计阅读时间需要7分钟。

如何实现Redis缓存中泛型集合与JSON字符串的互转示例?

难点是如何将泛型类型如ArrayList和Object转换为JSON字符串,并存储到Redis缓存中。以下是简化后的代码:

java// 将ArrayList类型的数据转换为JSON字符串并存储到Redis缓存ArrayList listProfit=new ArrayList();// 假设listProfit已经被填充了数据

// 将ArrayList转换为JSON字符串String listProfitPctJsonStr=JSON.toJSONString(listProfit);

// 存储到Redis缓存redisTemplate.opsForValue().set(listProfit, listProfitPctJsonStr);

难点是泛型如何转换

一、arrayList<Map<String, Object>>转化json字符串,存入redis缓存

ArrayList<Map<String, Object>> listProfit //将ArrayList<Map<String, Object>>类型数据转换成json字符串 String listProfitPctJsonStr = JSON.toJSONString(listProfit); //然后将json字符串存入redis缓存,唯一key value JedisUtils.setex("listProfit", 600,listProfitPctJsonStr);

二、json字符串转回ArrayList<Map<String, Object>>(难点)

List<Map<String, Object>> listProfit=null; //先从redis里面去查询数据,看是否能获取到对应json字符串 String jsonStrLp=JedisUtils.get("listProfit"); //如果能获取则说明缓存中有数据 if(!StringUtils.isBlank(jsonStrLp)){ //目的是为了泛型的转换 listProfit=new ArrayList<Map<String,Object>>(); //先把从redis缓存中取出来的json字符串转为List<Map>集合 List<Map> mapList=JSON.parseArray(jsonStrLp, Map.class); //然后循环遍历这个List集合,得出的结果为Map,然后再强转为Map<String,Object>, 再循环 把 Map<String,Object>添加到List集合中,搞定!!! for (Map map : mapList) { Map<String,Object> sObj=(Map<String,Object>)map; listProfit.add(sObj); }

补充知识:Java的List和Json转换以及StringRedisTemplate往redis存泛型对象

List转Json

List<User> user= new ArrayList();

String str = JSON.toJSONString(user);

Json 转List方法一

List<User> user= JSON.parseArray(json,User.class);

如果是泛型方法需要使用TypeReference

Json 转List 方法二

String json = "[{}]";

List<user> user= JSON.parseObject(json,new TypeReference<List<User>>(){});

泛型T

Json 转List方法三

List<T> students = JSON.parseObject(listCache,new TypeReference<List<T>>(){});

综合例子:Springboot环境下利用StringRedisTemplate往redis存泛型对象

一开始要注入下StringRedisTemplate

@Autowired

private StringRedisTemplate redisTemplate;

Redis获取值不存在就从数据库取出来json化存缓存,存在则直接反序列化json为List

List<T> list; String listCache=redisTemplate.opsForValue().get(key); if(listCache!=null){ list = JSON.parseObject(listCache,new TypeReference<List<T>>(){}); } else { list = userService.getAllList(); redisTemplate.opsForValue().set(key, JSON.toJSONString(list), 60 * 1, TimeUnit.SECONDS); }

附录:TypeReference源码

package com.alibaba.fastjson; import java.lang.reflect.GenericArrayType; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import com.alibaba.fastjson.util.ParameterizedTypeImpl; import com.alibaba.fastjson.util.TypeUtils; /** * Represents a generic type {@code T}. Java doesn't yet provide a way to * represent generic types, so this class does. Forces clients to create a * subclass of this class which enables retrieval the type information even at * runtime. * * <p>For example, to create a type literal for {@code List<String>}, you can * create an empty anonymous inner class: * * <pre> * TypeReference&lt;List&lt;String&gt;&gt; list = new TypeReference&lt;List&lt;String&gt;&gt;() {}; * </pre> * This syntax cannot be used to create type literals that have wildcard * parameters, such as {@code Class<?>} or {@code List<? extends CharSequence>}. */ public class TypeReference<T> { static ConcurrentMap<Type, Type> classTypeCache = new ConcurrentHashMap<Type, Type>(16, 0.75f, 1); protected final Type type; /** * Constructs a new type literal. Derives represented class from type * parameter. * * <p>Clients create an empty anonymous subclass. Doing so embeds the type * parameter in the anonymous class's type hierarchy so we can reconstitute it * at runtime despite erasure. */ protected TypeReference(){ Type superClass = getClass().getGenericSuperclass(); Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0]; Type cachedType = classTypeCache.get(type); if (cachedType == null) { classTypeCache.putIfAbsent(type, type); cachedType = classTypeCache.get(type); } this.type = cachedType; } /** * @since 1.2.9 * @param actualTypeArguments */ protected TypeReference(Type... actualTypeArguments){ Class<?> thisClass = this.getClass(); Type superClass = thisClass.getGenericSuperclass(); ParameterizedType argType = (ParameterizedType) ((ParameterizedType) superClass).getActualTypeArguments()[0]; Type rawType = argType.getRawType(); Type[] argTypes = argType.getActualTypeArguments(); int actualIndex = 0; for (int i = 0; i < argTypes.length; ++i) { if (argTypes[i] instanceof TypeVariable && actualIndex < actualTypeArguments.length) { argTypes[i] = actualTypeArguments[actualIndex++]; } // fix for openjdk and android env if (argTypes[i] instanceof GenericArrayType) { argTypes[i] = TypeUtils.checkPrimitiveArray( (GenericArrayType) argTypes[i]); } // 如果有多层泛型且该泛型已经注明实现的情况下,判断该泛型下一层是否还有泛型 if(argTypes[i] instanceof ParameterizedType) { argTypes[i] = handlerParameterizedType((ParameterizedType) argTypes[i], actualTypeArguments, actualIndex); } } Type key = new ParameterizedTypeImpl(argTypes, thisClass, rawType); Type cachedType = classTypeCache.get(key); if (cachedType == null) { classTypeCache.putIfAbsent(key, key); cachedType = classTypeCache.get(key); } type = cachedType; } private Type handlerParameterizedType(ParameterizedType type, Type[] actualTypeArguments, int actualIndex) { Class<?> thisClass = this.getClass(); Type rawType = type.getRawType(); Type[] argTypes = type.getActualTypeArguments(); for(int i = 0; i < argTypes.length; ++i) { if (argTypes[i] instanceof TypeVariable && actualIndex < actualTypeArguments.length) { argTypes[i] = actualTypeArguments[actualIndex++]; } // fix for openjdk and android env if (argTypes[i] instanceof GenericArrayType) { argTypes[i] = TypeUtils.checkPrimitiveArray( (GenericArrayType) argTypes[i]); } // 如果有多层泛型且该泛型已经注明实现的情况下,判断该泛型下一层是否还有泛型 if(argTypes[i] instanceof ParameterizedType) { return handlerParameterizedType((ParameterizedType) argTypes[i], actualTypeArguments, actualIndex); } } Type key = new ParameterizedTypeImpl(argTypes, thisClass, rawType); return key; } /** * Gets underlying {@code Type} instance. */ public Type getType() { return type; } public final static Type LIST_STRING = new TypeReference<List<String>>() {}.getType(); }

TypeReference的存在是因为java中子类可以获取到父类泛型的真实类型。

其中核心的方法是:getActualTypeArguments,它可以得到父类的反省类型

ParameterizedType是一个记录类型泛型的接口, 继承自Type,一共三方法:

Type[] getActualTypeArguments(); //返回泛型类型数组 Type getRawType(); //返回原始类型Type Type getOwnerType(); //返回 Type 对象,表示此类型是其成员之一的类型。

Map<String, Integer> intMap = new HashMap<>(); System.out.println("getSuperclass:" + intMap.getClass().getSuperclass()); System.out.println("getGenericSuperclass:" + intMap.getClass().getGenericSuperclass()); Type type = intMap.getClass().getGenericSuperclass(); if (type instanceof ParameterizedType) { ParameterizedType p = (ParameterizedType)type; for (Type t : p.getActualTypeArguments()) { System.out.println("getActualTypeArguments>>>"+t); } }

如何实现Redis缓存中泛型集合与JSON字符串的互转示例?

扩展阅读Java如何获得泛型类的真实类型:

package com.paopaoedu.springboot.demo; import com.paopaoedu.springboot.bean.User; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; public class BaseDao<T>{ private Class<T> clazz; // 使用反射技术得到T的真实类型 public Class getRealType(){ Class c=this.getClass(); //getSuperclass()获得该类的父类 System.out.println("getSuperclass >>>"+c.getSuperclass()); //getGenericSuperclass()获得带有泛型的父类 System.out.println("getGenericSuperclass >>>"+c.getGenericSuperclass()); //Type是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。 Type type=c.getGenericSuperclass(); System.out.println("Type >>>"+type); //ParameterizedType参数化类型,即泛型 // 获取当前new的对象的泛型的父类类型 ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass(); // 获取第一个类型参数的真实类型 this.clazz = (Class<T>) pt.getActualTypeArguments()[0]; c=(Class) pt.getActualTypeArguments()[0]; System.out.println(c); return clazz; } } class userdemo extends BaseDao<User>{ public static void main(String[] args) { userdemo classB = new userdemo(); Class realType = classB.getRealType(); System.out.println(realType.getName()); } }

以上这篇Redis缓存,泛型集合与json字符串的相互转换实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持易盾网络。

标签:相互