这是一个棘手的数据结构和数据组织案例。
我有一个应用程序从大文件中读取数据并生成各种类型的对象(例如Boolean
,Integer
,String
),这些对象分为少数(小于1)打了几个组,然后存储在数据库中。
每个对象当前存储在单个HashMap<String, Object>
数据结构中。每个这样的HashMap
对应于单个类别(组)。每个数据库记录都是根据所有类别(HashMap数据结构)中包含的所有对象中的信息构建的。
出现了一个要求,用于检查后续记录是否与列的数量和类型“等效”,其中必须通过比较名称(HashMap
键)和类型(实际类别)来验证所有映射的等效性)每个存储对象。
我正在寻找一种有效的方法来实现此功能,同时保持原始对象分类,因为以最快的方式按类别列出对象也是一项要求。
一个想法是只对键进行排序(例如,将每个HashMap
替换为TreeMap
),然后遍历所有地图。另一种方法是只复制TreeMap
中的所有内容,仅用于比较目的。
实现此功能的最有效方法是什么?
另外,如果您要如何在连续记录之间找到差异(即添加的字段和删除的字段)?
答案 0 :(得分:2)
一个解决方案是保持基于类别HashMap
和合并TreeMap
。这会有更多的内存需求,但不会太多,因为你只需要在它们中保留相同的引用。
因此,无论何时添加/删除HashMap
,您都会在TreeMap
中执行相同的操作。这样两者都将始终保持同步。
然后,您可以使用TreeMap进行比较,无论您是想要比较对象类型还是实际内容比较。
答案 1 :(得分:2)
创建一个元SortedSet,您可以在其中存储所有已创建的地图。
表示SortedSet<Map<String,Object>>
,例如一个TreeSet
作为自定义Comparator<Map<String,Object>>
,它确实检查了您对相同数量和键名称以及每个值的相同对象类型的要求。
然后,您可以使用此元集结构的contains()方法来确定是否已存在类似的记录。
====编辑====
由于我首先误解了数据库记录和地图之间的关系,所以我现在要改变一些语义我的答案。
我仍然会使用上面提到的SortedSet<Map<String,Object>>
,但当然Map<String,Object>
现在会指向你和thexy建议的地图。
另一方面,使用Set<Set<KeyAndType>>
或SortedSet<Set<KeyAndType>>
可能是向前迈出的一步,其中您的KeyAndType只包含密钥和具有适当Comparable
实现的类型或{{1 }}。
为什么呢?你问过如何找到两个记录之间的差异?如果每个记录与其中一个内部equals with hashcode
相关,则可以轻松使用Set<KeyAndType>
形成两个连续集合的交集。
如果你将它与retainAll()
的想法进行比较,那么在两种方式中你都会得到比较器中字段之间差异的逻辑,一次比较内部集合,一次比较内部映射。并且由于在构造周围集合时此信息会丢失,因此如果您没有其他易于使用的简化结构来查找此类差异,则很难在以后获取两个记录之间的差异。而且由于这样的SortedSet<Map<String,Object>>
可以作为两个记录之间进行比较的关键和简单基础,因此它可以成为两个目的的良好候选者。
如果您想进一步保持这样的Set<KeyAndType>
与您的记录或Set<KeyAndType>
组之间的关系,您的元结构可能类似于:
Map<String,Object>
或Map<Set<KeyAndType>,DatabaseRecord>
由简单的Map<Set<KeyAndType>,GroupOfMaps>
实现,允许按原始顺序进行简单迭代。