Redis緩存,泛型集合與json字符串的相互轉(zhuǎn)換實(shí)例
難點(diǎn)是泛型如何轉(zhuǎn)換
一、arrayList<Map<String, Object>>轉(zhuǎn)化json字符串,存入redis緩存
ArrayList<Map<String, Object>> listProfit
//將ArrayList<Map<String, Object>>類型數(shù)據(jù)轉(zhuǎn)換成json字符串
String listProfitPctJsonStr = JSON.toJSONString(listProfit);
//然后將json字符串存入redis緩存,唯一key value
JedisUtils.setex("listProfit", 600,listProfitPctJsonStr);
二、json字符串轉(zhuǎn)回ArrayList<Map<String, Object>>(難點(diǎn))
List<Map<String, Object>> listProfit=null;
//先從redis里面去查詢數(shù)據(jù),看是否能獲取到對(duì)應(yīng)json字符串
String jsonStrLp=JedisUtils.get("listProfit");
//如果能獲取則說(shuō)明緩存中有數(shù)據(jù)
if(!StringUtils.isBlank(jsonStrLp)){
//目的是為了泛型的轉(zhuǎn)換
listProfit=new ArrayList<Map<String,Object>>();
//先把從redis緩存中取出來(lái)的json字符串轉(zhuǎn)為L(zhǎng)ist<Map>集合
List<Map> mapList=JSON.parseArray(jsonStrLp, Map.class);
//然后循環(huán)遍歷這個(gè)List集合,得出的結(jié)果為Map,然后再?gòu)?qiáng)轉(zhuǎn)為Map<String,Object>,
再循環(huán) 把 Map<String,Object>添加到List集合中,搞定?。?!
for (Map map : mapList) {
Map<String,Object> sObj=(Map<String,Object>)map;
listProfit.add(sObj);
}
補(bǔ)充知識(shí):Java的List和Json轉(zhuǎn)換以及StringRedisTemplate往redis存泛型對(duì)象
List轉(zhuǎn)Json
List<User> user= new ArrayList();
String str = JSON.toJSONString(user);
Json 轉(zhuǎn)List方法一
List<User> user= JSON.parseArray(json,User.class);
如果是泛型方法需要使用TypeReference
Json 轉(zhuǎn)List 方法二
String json = "[{}]";
List<user> user= JSON.parseObject(json,new TypeReference<List<User>>(){});
泛型T
Json 轉(zhuǎn)List方法三
List<T> students = JSON.parseObject(listCache,new TypeReference<List<T>>(){});
綜合例子:Springboot環(huán)境下利用StringRedisTemplate往redis存泛型對(duì)象
一開(kāi)始要注入下StringRedisTemplate
@Autowired
private StringRedisTemplate redisTemplate;
Redis獲取值不存在就從數(shù)據(jù)庫(kù)取出來(lái)json化存緩存,存在則直接反序列化json為L(zhǎng)ist
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<List<String>> list = new TypeReference<List<String>>() {};
* </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]);
}
// 如果有多層泛型且該泛型已經(jīng)注明實(shí)現(xiàn)的情況下,判斷該泛型下一層是否還有泛型
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]);
}
// 如果有多層泛型且該泛型已經(jīng)注明實(shí)現(xiàn)的情況下,判斷該泛型下一層是否還有泛型
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的存在是因?yàn)閖ava中子類可以獲取到父類泛型的真實(shí)類型。
其中核心的方法是:getActualTypeArguments,它可以得到父類的反省類型
ParameterizedType是一個(gè)記錄類型泛型的接口, 繼承自Type,一共三方法:
Type[] getActualTypeArguments(); //返回泛型類型數(shù)組 Type getRawType(); //返回原始類型Type Type getOwnerType(); //返回 Type 對(duì)象,表示此類型是其成員之一的類型。
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);
}
}


擴(kuò)展閱讀Java如何獲得泛型類的真實(shí)類型:
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;
// 使用反射技術(shù)得到T的真實(shí)類型
public Class getRealType(){
Class c=this.getClass();
//getSuperclass()獲得該類的父類
System.out.println("getSuperclass >>>"+c.getSuperclass());
//getGenericSuperclass()獲得帶有泛型的父類
System.out.println("getGenericSuperclass >>>"+c.getGenericSuperclass());
//Type是 Java 編程語(yǔ)言中所有類型的公共高級(jí)接口。它們包括原始類型、參數(shù)化類型、數(shù)組類型、類型變量和基本類型。
Type type=c.getGenericSuperclass();
System.out.println("Type >>>"+type);
//ParameterizedType參數(shù)化類型,即泛型
// 獲取當(dāng)前new的對(duì)象的泛型的父類類型
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
// 獲取第一個(gè)類型參數(shù)的真實(shí)類型
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字符串的相互轉(zhuǎn)換實(shí)例就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java+MySQL實(shí)現(xiàn)設(shè)計(jì)優(yōu)惠券系統(tǒng)
這篇文章主要介紹了Java+MySQL實(shí)現(xiàn)設(shè)計(jì)優(yōu)惠券系統(tǒng),文章基于Java與MySQL的相關(guān)資料展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-05-05
JAVA中String類與StringBuffer類的區(qū)別
這篇文章主要為大家詳細(xì)介紹了JAVA中String類與StringBuffer類的區(qū)別,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12
劍指Offer之Java算法習(xí)題精講數(shù)組與二叉樹(shù)
跟著思路走,之后從簡(jiǎn)單題入手,反復(fù)去看,做過(guò)之后可能會(huì)忘記,之后再做一次,記不住就反復(fù)做,反復(fù)尋求思路和規(guī)律,慢慢積累就會(huì)發(fā)現(xiàn)質(zhì)的變化2022-03-03

