在“Redis学习总结和相关资料”http://blog.csdn.net/fansunion/article/details/49278209
这篇文章中,对Redis做了总体的介绍,演示了Jedis和SpringDataRedis访问Redis的相关例子。
对于基本的CRUD差不多够了。
随着项目中使用场景的增多,出现了存储Java集合List的情况。
这个时候,一般的代码很可能会报错,比如“无法序列化”,“序列化失败”之类的~
经过几个小时的实践探索,参考了在秒针工作的代码以及最近的代码,有2种可行方法。
需要说明的是,项目中用的是SpringDataRedis,但是Jedis代码的思路也是一样的。
项目中的Redis配置
<bean id="businessRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
<property name="connectionFactory" ref="businessConnectionFactory" />
<!--如果不配置Serializer,那么存储的时候智能使用String,如果用User类型存储,那么会提示错误User can't cast
to String!!! -->
<property name="keySerializer">
<bean
class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean
class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
</property>
</bean>

直接存储java.util.List会提示“无法序列化”,“JdkSerializationRedisSerializer序列化失败”类似的错误,
简单的把java.util.List的元素实现Serialiable接口,是不行的。
也考虑了下,是不是和List元素的serialVersionUID有关系,最初用的是默认值1,改成系统生成的,也还是不行.
private static final long serialVersionUID = -2162380932844568332L;
方法1:把List转换成JSON,存储到Redis,取出来的时候,再把JSON转换成List。
这种方法也很不错,但是,当时咋就没有想到呢。
序列化存储
 
List list = new ArrayList();
String json=JSONObject.toJSONString(list);
logger.info("save json="+json);
defaultCache.add(key, json, CATCHE_TIME);

 
反序列化
     
  Object jsonInRedis = defaultCache.getValue(key);
List<MatchContent> list = null;
Object listInRedis = null;
if(jsonInRedis != null){
logger.info("get json="+jsonInRedis);
listInRedis= JSONObject.parseArray(jsonInRedis.toString(), MatchContent.class);
}
if (listInRedis instanceof List) {
list = (List) listInRedis;
logger.debug("Find fund4Project in redis~ size=" + list.size());
}

需要特别说明的是, JSONObject.parseArray可以把json格式的字符串,转换成Java的List。
这个方法之前用的少,一直不熟悉,第2个参数是List元素的class。
  自己写的1个Demo。
public static void main(String[] args) {
List list = new ArrayList();
list.add(new User());
String json=JSONObject.toJSONString(list);
System.out.println(json);
List newList=JSONObject.parseArray(json, User.class);
System.out.println(newList.size()); }

方法2:把List转换成二进制数组byte[],存储到Redis,取出来的时候,再把byte[]转成List。
序列化list->byte[]
import hprose.io.HproseFormatter;
java.io.ByteArrayOutputStream baos=HproseFormatter.serialize(list);
byte[] bytes=baos.toByteArray();

二进制反序列化byte[]->list
 listInRedis = HproseFormatter.unserialize((byte[] )bytesInRedis);
 
 项目中用的是源代码,从秒针代码中copy出来的库。
 
 上述2种方法,使用JSON序列化存储,感觉更简单一些。
 但是据说HproseFormatter这个库,很牛逼,按照官网的说法。
 Hprose(High Performance Remote Object Service Engine)
是一款先进的轻量级、跨语言、跨平台、无侵入式、高性能动态远程对象调用引擎库。它不仅简单易用,而且功能强大。
你无需专门学习,只需看上几眼,就能用它轻松构建分布式应用系统。
 网上找到了hprose的资料,不出意外的话,可以用下面这个的。
 hprose/hprose-java
 https://github.com/hprose/hprose-java/tree/master/src
  
  Map等其它类型的存储,和List类似~
  
  把Redis序列化这个问题解决了,感觉方法很简单。
 还是那句经典的话“难题不会,会题不难”。
 等把问题解决了,再难的问题,已经变得简单了。没解决的时候,急死你。
 伙计,加油~

Redis序列化存储Java集合List等自定义类型的更多相关文章

  1. Java集合框架实现自定义排序

    Java集合框架针对不同的数据结构提供了多种排序的方法,虽然很多时候我们可以自己实现排序,比如数组等,但是灵活的使用JDK提供的排序方法,可以提高开发效率,而且通常JDK的实现要比自己造的轮子性能更优 ...

  2. java编程排序之自定义类型的集合,按业务需求排序

    自定义引用类型放入集合中,按实际业务需求进行排序的两种思路 第一种思路: (1)自定义实体类实现java.lang.Comparable接口,重写public int compareTo(Object ...

  3. [Java]如何为一个自定义类型的List排序。

    好吧,三年了,又重拾我的博客了,是因为啥呢,哈哈哈.今天被问到一个题目,当场答不出来,动手动的少了,再此记录下来. Q:有一个MyObject类型的List,MyObject定义如下: class M ...

  4. java集合 collection-list-ArrayList 将自定义对象作为元素存到ArrayList集合中,并去除重复元素。

    import java.util.*; /* 将自定义对象作为元素存到ArrayList集合中,并去除重复元素. 比如:存人对象.同姓名同年龄,视为同一个人.为重复元素. 思路: 1,对人描述,将数据 ...

  5. java利用自定义类型对树形数据类型进行排序

    前言 为什么集合在存自定义类型时需要重写equals和hashCode? 1.先说List集合 List集合在存数据时是可以重复的但是 当我们需要判断一个对象是否在集合中存在时这样就有问题了! 因为我 ...

  6. 【集合】Java集合框架

    Java类库中帮助我们在程序设计中实现了传统的数据结构.本文章跳过理论部分,主要介绍如何使用标准库中的集合类. 1 将集合的接口与实现分离 Java集合类库将接口与实现分离.以队列为例: public ...

  7. go-redis 基于beego正确使用序列化存储数据和反序列化获取数据

    安装go-redis // 安装命令 go get github.com/gomodule/redigo/redis // 导入使用 import( "github.com/gomodule ...

  8. 五、Java - 集合

    一.集合 Java 中的集合类存放于 java.util 包中,是一个存放对象的容器. 集合存放的是对对象的引用,对象本身还是存在于 JVM 堆内存中. 存放的是对象,即引用数据类型,对于基本数据类型 ...

  9. C#自定义类型数组排序

    在数组或者集合中对自定义类型进行排序分为两种方法. 1.如果这个自定义类型是自己定义编写的,那么我可以使它继承ICompareable<T>接口,实现其中的CompareTo(Object ...

随机推荐

  1. php获取当前月份的前(后)几个月

    //获取当前月份的前一月 function GetMonth($sign) { //得到系统的年月 $tmp_date=date("Ym"); //切割出年份 $tmp_year= ...

  2. size_type类型

    由string类类型和vector类类型定义的类型,用以保存任意string对象或vector对象的长度,标准库类型将size_type定义为unsigned类型 string::size_type它 ...

  3. mysql中如何查看某个数据库或表占用的磁盘空间

    查整个库的状态:select concat(truncate(sum(data_length)/1024/1024,2),'MB') as data_size,          concat(tru ...

  4. 在学校机房联想硬盘保护下安装Linux,并配置锐捷客户端

    最近几天一直在机房里刷题,空调开着非常舒服.但是机房电脑里全是windows系统,不太好用,挺膈应人的. 一直打算换个系统,刚才终于搞定网络问题了,以后用电脑就可以爽到了. 联想硬盘保护系统下u盘安装 ...

  5. POJ 3093 Margaritas on the River Walk(背包)

    题意 n个有体积的物品,问选取一些物品,且不能再继续选有多少方法? n<=1000 题解 以前的考试题.当时是A了,但发现是数据水,POJ上WA了. 把体积从小到大排序枚举没选的物品中体积最小的 ...

  6. [Vijos P2000]A x B Problem

    题目大意:叫你求A × B. 解题思路:高精度.你可千万别小看这道题,这是2017年7月27日的信息. 不过也不要怕,根据twd2的题解里写的,用普通的高精度加上一些小小的修改是可以过的. 那么直接上 ...

  7. Bedrock Linux 0.7.3 发布

    Bedrock Linux是一种元分发,允许用户利用其他通常互斥的Linux发行版的功能,并让它们无缝地一起工作.该项目发布了其0.7.x系列,Bedrock Linux 0.7.3的更新. 新的更新 ...

  8. python基础4(小数据池,编码,深浅拷贝)

    1.==与is == 比较值是否相等 is比较内存地址是否相同 2.小数据池 为了节省内存,当数据在一个范围里的时候,两个值相同的变量指向的是小数据池里的同一个地址 数字范围:-5 ~ 256 num ...

  9. ifram 实现左侧菜单,右侧显示内容

    一般都是左侧的导航栏中的a标签中写一个target(a标签有target属性), 右侧的div标签中写一个iframe,在iframe中有name的属性,在左侧a标签中的target写上iframe中 ...

  10. leetcode 刷题之路 66 Path Sum II

    Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given su ...