我们有一种情况,我们最终使用多级哈希映射;也就是说,哈希映射内部的哈希映射,深度为三层或四层。
本能地在某处感觉不对劲。我在这里阅读了有关如何迭代/使用多级哈希映射的帖子,但几乎没有人说这是最佳实践。
为什么多级哈希映射不好,哪个更好的设计(如果有的话)?
以下是我们拥有的多级哈希映射的示例设计:
Map<String, Object1> map1;
class Object1 {
String version;
Map<String,Object2> map2;
}
class Object2 {
Map<String,List<Object3>> map4;
Map<String,String> map5;
}
答案 0 :(得分:4)
只要它们被正确抽象化,它就不是 大部分的交易,但是你在可读性方面让自己陷入了一些讨厌的兔子洞。如果没有抽象,维持这种情况就会变成 噩梦 ,而开发人员不希望这样做。
基本上,你正在创造的是一张表;第一个密钥是访问更多列的主键。在简单的一,二或三级设计中,这并不可怕;你需要三个键来获得一个值。如果有一种方便的方式来访问它,如下所示,它不是一个可怕的想法(虽然那里有更好的)。
public interface Table<K1, K2, K3, V> {
V get(K1 key1, K2 key2, K3 key3);
}
...但是,这完全取决于您实际使用该数据结构做什么。如果您发现自己试图迭代值的中间键(也就是说,您正在查看键3以获取它与键5之间的所有值的集合),那么您必须重新考虑您的业务逻辑。提供的数据结构不够灵活,无法处理所有案例;或多或少,它用于基于一组值的简单索引。
或者,人们可以查看Guava Table
,因为它做同样的事情,有一个更好的界面(类似于我上面的那个)。
答案 1 :(得分:1)
多级HashMaps不一定是坏的,这取决于你的算法。 糟糕的是管理起来比较困难。 考虑使用HasMap值的接口(类似于存储库),这可能会使您的设计更清晰。 其他选项是在HashMap中使用复合键。
答案 2 :(得分:1)
我认为在HashMap
内执行HashMap
是不好的做法,因为为了扩展您的HashMap,您需要花费时间和金钱。从3
级别深度Map
到5
级别深度Map
,您基本上必须重新编写您的类。在维护这个项目时,这会带来很多技术债务。
在某处声明初始地图
Map<String, MyHashedObject> HashKVP = new HashMap<String, MyHashedObject>();
然后让Object
存储其他地图。
class MyHashedObject {
private Map<String, MyHashedObject> InternalKvp;
public MyHashedObject() {
this.InternalKvp = new HashMap<String, MyHashedObject>();
}
/*
* Get the next level of our MyHashedObject object
* @param HashKey
* @return MyHashedObject result
*/
public MyHashedObject findHashedObject(String HashKey) {
MyHashedObject result = null;
if(this.InternalKvp.containsKey(HashKey)) {
result = this.InternalKvp.get(HashKey);
}
return result;
}
}
通过这种方式,只需将更多对象转储到HashMap
即可轻松将更多关卡扩展到InternalKvp
。
这只是一个非常基本的示例,但您可以向MyHashedObject
添加更多属性(例如depth
,parent_object
等)。您可以执行类似Small-world network的操作,以跟踪每个对象的depth
。
使用RedBlackTree
或AVLTree
可以更好地完成此操作,以便更轻松地遍历Maps
。