软件编程
位置:首页>> 软件编程>> java编程>> Redis缓存,泛型集合与json字符串的相互转换实例

Redis缓存,泛型集合与json字符串的相互转换实例

作者:一只咸鱼的自我修养  发布时间:2021-07-18 16:57:15 

标签:Redis,缓存,泛型,json

难点是泛型如何转换

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

Redis缓存,泛型集合与json字符串的相互转换实例

Redis缓存,泛型集合与json字符串的相互转换实例

附录: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字符串的相互转换实例

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字符串的相互转换实例

来源:https://blog.csdn.net/weixin_40671802/article/details/79426243

0
投稿

猜你喜欢

手机版 软件编程 asp之家 www.aspxhome.com