使用TreeSet导致序列化异常java.io.NotSerializableException
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了使用TreeSet导致序列化异常java.io.NotSerializableException,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3044字,纯文字阅读大概需要5分钟。
内容图文
使用TreeSet导致序列化异常
- 问题描述:对一级分类下面的二级分类按照order字段(Integer类型)进行排序,当时弄了个TreeSet,传了个自定义Comparator,在本地跑没问题,排序也排好了,在测试环境也通过了,结果这玩意一到线上,就报序列化异常,线上环境加了缓存。查资料说TreeSet这里有个bug不能进行序列化,顿时就郁闷了。
- 异常信息如下
- 场景描述
现模拟一下需求对应的JavaBean如下:
public class ProductCategory implements Serializable {
private String id;
private String name;
private Integer order;
private Set<ProductCategory> children = new HashSet<>();
}
省略getter,setter方法,线上环境用的hibernate,以前的JavaBean,用很久了,不敢改动。子分类对应一个HashSet(), 而这个HashSet是无序的,现需要对这个children子分类排序,模拟测试如下:
@Test
public void contextLoads() {
ProductCategory productCategory = new ProductCategory();
// 创建4个子类对象
ProductCategory children1 = new ProductCategory();
ProductCategory children2 = new ProductCategory();
ProductCategory children3 = new ProductCategory();
ProductCategory children4 = new ProductCategory();
// ID
children1.setId(UUID.randomUUID().toString());
children2.setId(UUID.randomUUID().toString());
children3.setId(UUID.randomUUID().toString());
children4.setId(UUID.randomUUID().toString());
// name
children1.setName(UUID.randomUUID().toString());
children2.setName(UUID.randomUUID().toString());
children3.setName(UUID.randomUUID().toString());
children4.setName(UUID.randomUUID().toString());
// order 排序字段
children1.setOrder(10);
children2.setOrder(8);
children3.setOrder(9);
children4.setOrder(12);
// 传一个TreeSet替换HashSet,自定义一个比较器通过order字段比较(对于Comparator用法不熟的自行百度)
productCategory1.setChildren(new TreeSet<>(Comparator.comparingInt(o -> o.getOrder() == null ? 0 : o.getOrder())));
// 都添加到HashSet中
productCategory.getChildren().add(children1);
productCategory.getChildren().add(children2);
productCategory.getChildren().add(children3);
productCategory.getChildren().add(children4);
////////////////////////////////////////
// 到这里,children里面都已经按照order(8,9,10,12)排好了, 就不放打印结果了,可自行debug查看。
////////////////////////////////////////
// 模拟线上缓存,存redis一份(结果这一步就报了java.io.NotSerializableException)
redisTemplate.opsForValue().set("productcategory", productCategory.getChildren());
}
- 解决方式
// 仍然使用原来的HashSet
productCategory2.getChildren().add(children1);
productCategory2.getChildren().add(children2);
productCategory2.getChildren().add(children3);
productCategory2.getChildren().add(children4);
// 将HastSet转成List
List<ProductCategory> list = new ArrayList<>(productCategory1.getChildren());
// 排序
Collections.sort(list, (Comparator.comparingInt(o -> (o.getOrder() == null ? 0 : o.getOrder()))));
// 排完转成LinkedHashSet再塞回去就能保证有序了
productCategory1.setChildren(new LinkedHashSet<>(list));
// 模拟线上缓存,存redis一份(这里也可以正常序列化了)
redisTemplate.opsForValue().set("productcategory", productCategory.getChildren());
对于HashSet的默认排序是按照HashCode排的,再不影响业务的情况下,也可以重写hashCode()方法,或者实现Comparable接口重写compareTo方法。
内容总结
以上是互联网集市为您收集整理的使用TreeSet导致序列化异常java.io.NotSerializableException全部内容,希望文章能够帮你解决使用TreeSet导致序列化异常java.io.NotSerializableException所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。