我的服务器上有一个Java对象列表,它通过一些序列化机制发送给客户端。偶尔会在服务器上更新对象列表,也就是说,某些对象会被添加,有些会被删除而其他对象只会更改它们在列表中的位置。我想在客户端更新List,但发送尽可能少的数据。特别是,我不想重新发送客户端上已有的对象。
是否有可用的库可以从两个列表中产生某种差异,这样我只能发送差异和新的对象?
我找到了unix diff命令的几个Java实现,但是这个算法对于顺序更改是不实用的。即。 [A,B,C] - > [C,B,A]可以仅作为地点更改[1-> 3] [3-> 1]发送,而diff将要重新发送整个A和C对象(据我所知)。 / p>
答案 0 :(得分:3)
我会通过将对象的公共接口静默地保存在任何位置来保留所做更改的日志,即将表示每个修改的对象添加到修改列表中来实现。
通过这种方式,您可以获得发送到其他计算机的确切更改的最小列表,而不需要通过比较旧版和新版来使用错误的猜测来推断它们。
要创建对象模型以便自动记录对自身的更改,您可能会从一些代码生成或AOP中受益,以避免大量重复模式。设置属性值或从列表中添加/删除的方法都需要调用对象层次结构共享的中央日志。
答案 1 :(得分:3)
您可以“假装”您的列表是字符串,并使用Damerau–Levenshtein distance查找将其转换为另一个所需的最少操作,允许插入,删除,替换和转置 (这是你的例子所暗示的。)
我不知道成熟和/或稳定的实现,即使存在,它也可能是字符串的目标,因此适应抽象值类型列表将是一个挑战。实现你自己也可能是一项具有挑战性的任务,但它肯定是可行的。
答案 2 :(得分:1)
JaVers lib(http://javers.org)完成这项工作。
Diff diff = javers.compare(list1, list2);
Diff包含以下更改列表:对象添加,对象删除,索引更改
答案 3 :(得分:0)
现在我只是通过网络发送完整的List,但是我只使用一个唯一的ID而不是对象。如果客户端本地没有该对象,则使用该ID请求它。
这肯定不如最佳算法漂亮,但具有预期的结果:昂贵的物体只能通过电线发送一次。