RFID读卡器增量更新思路与代码实现
0.项目背景
上一篇文章中提到机器人项目中调用摄像头获取实时画面,这次又来了一个新的需求,要使用RFID读卡器识别区域内的商品ID并上传云端,最后由云端返回该商品信息数据。区域内的商品随时可能增加或者减少。因此我想要达到当区域内数据发生变化时根据增加或者减少的数据发送消息进行更新,从而达到增量更新的效果。
1.RFID读卡器模式
RFID厂商提供了两种盘库模式一种是实时模式,一种是缓存模式。
1.1 实时模式:
即读到标签ID时立即上传,实时发送最新的数据
优点
:多标签识别性能好,相应迅速,用户可以在第一时间得到标签的数据,没有延时。
缺点
:会产生大量的数据。
1.2 缓存模式:即读到标签的ID后,先放入读卡器缓存,最后在需要的时候一次性将缓存中的所有ID上传。
优点
:汇总上传的数据是经过过滤的没有重复的数据。
缺点
:识别大量标签时每次都需要逐一对比标签信息以过滤重复数据,效率低。另外在读取缓存中的标签数据时是不能进行读写标签操作的。
2.开发思路
显然厂商提供的两种模式并不能满足我们的需求,但是实时模式与我们的需求比较接近,所以我们从实时模式入手。实时模式每次都是将最新的数据发送出来,会造成大量的数据传输,我们只需要将最近一次数据与上次数据进行比较便可获取此次数据是否有更新。如果没有更新我们则不需要继续推送数据,一但检测到更新我们就更具数据的增加、删除进行数据发送,这样就可以大大的减少数据量兵器可以满足我们的需求。
3.开发过程
由思路我们用两个list分别存储最近数据与上次数据,得益于spring boot的service为单例模式所以可以直接保存上次的数据,而不被初始化覆盖。
private List<String> oldList = new ArrayList<>();
private List<String> newList = new ArrayList<>();
@Override
public void cache(List<String> rfidList) {
newList = rfidList;
/**
* 进行两个数组的比较
* 1、两个list比较,获取不同的元素列表
* newList - oldList = 要增加的元素
* oldList - newList = 要删除的元素
*/
List<String> add = newList.stream().filter(item -> !oldList.contains(item)).collect(toList());
if (add.size() > 0){
// TODO 发送增加指令直接发送newList数组到云端
System.out.println("增加");
}
List<String> remove = oldList.stream().filter(item -> !newList.contains(item)).collect(toList());
if (remove.size() > 0){
// TODO 发送删除指令 newList数组到前端
System.out.println("删除");
}
//将newList赋值给oldList 注意不能直接使用= 等号指向的是同一内存空间会跟随变化
oldList.clear();
for (String str : newList) {
oldList.add(str);
}
}
4.坑
在这个的开发中遇到一个坑,这个坑把我害得好惨,同时也暴漏了自己的基础知识薄弱还需要增强。记录下来这个坑希望对大家有所帮助同时也是给自己一个记录。
上面代码最后一步需要将newList赋值给oldList最早我直接使用=
来赋值
oldList = newList;
list中使用=赋值实际上是将oldList指向newList所指向的内存空间,这样随着newList在下次触发时的更新,由于oldList指向的是同一内存空间这样就造成了oldList与newList的数据永远相等。
总结:在此处赋值不能使用=
。