Java 使用嵌套哈希映射是一种不好的做法吗?
让我解释一下我的情况。我需要维护一些层次结构。在下面找到显示此层次结构的图像。我会在图片之后解释Java 使用嵌套哈希映射是一种不好的做法吗?,java,data-structures,hashmap,Java,Data Structures,Hashmap,让我解释一下我的情况。我需要维护一些层次结构。在下面找到显示此层次结构的图像。我会在图片之后解释 A | +--> A1.1 ---> X | | +--> A1 ---+--> A1.2 ---> Y | | | . +--> A2 . . . 从A到A1,A2…这是一种一对多的关系 从A1到A1.1、A1.2…这是一种一
A
| +--> A1.1 ---> X
| |
+--> A1 ---+--> A1.2 ---> Y
| |
| .
+--> A2 .
.
.
- 从
到A
这是一种一对多的关系A1,A2…
- 从
到A1
这是一种一对多的关系A1.1、A1.2…
- 从
到A1.1
和X
到A1.2
这是一种一对一的关系Y
HashMap
s来维护它。但后来我很快意识到更新变得非常困难
拥有多个HashMap
s意味着我必须自己处理不同关系之间的唯一性。例如,A1.1
也可以存在于根B
节点中。因此,我必须将A
附加到A1.1
中,以确保唯一性。现在,如果我必须修改A
的值,那么我就有大麻烦了,因为我用它将A
中的所有键限定为A_A1.1
现在我想我可以使用嵌套的HashMaps
来实现这一点。因此,这方面的代码变成:
HashMap<String, HashMap<String, HashMap<String, CustomObject>>> _worldsBiggestHash;
HashMap\u worldsBiggestHash;
这种做法行吗?我确实有很多簿记工作要做,因为我将使用嵌套哈希,但至少CRUD和唯一性问题会自行处理
如果这不好,有人能建议我使用另一个更好的结构吗 你的建议不可取 假设您的需求能够基于密钥在O(log(n))时间内获取项。 我建议采取以下措施之一,以更好地解决此问题:
显然,您需要对树进行建模。此树不一定与
TreeMap
明确相关。诚然,我不知道TreeMap
如何帮助表示整个结构(尽管它可以在单个树节点中使用)
您可以创建这样的类
class Node
{
private final String name;
private final Map<String, Node> children;
private final CustomObject customObject;
Node(String name, CustomObject customObject)
{
this.name = name;
this.children = new LinkedHashMap<String, Node>();
this.customObject = customObject;
}
String getName()
{
return name;
}
void addChild(Node child)
{
children.put(child.getName(), child);
}
void removeChild(String name)
{
children.remove(name);
}
Node getChild(String name)
{
return children.get(name);
}
Set<Node> getChildren()
{
return Collections.unmodifiableSet(
new LinkedHashSet<Node>(children.values()));
}
Node root = new Node("", null);
Node a1 = new Node("A1", null);
Node a2 = new Node("A2", null);
root.addChild(a1);
root.addChild(a2);
Node a11 = new Node("A11", x);
Node a12 = new Node("A12", y);
a1.addChild(a11);
a1.addChild(a12);
这将允许您在层次结构中导航,并且维护关系将非常容易
我没有完全理解你所说的“独特性”。在任何情况下,在这样的树中,每个节点都由路径唯一标识。您甚至可以创建一个实用方法,如
CustomObject c = root.find("A", "A1", "A11");
通过节点名称序列快速访问对象
旁白:正如已经指出的,深度嵌套的映射(或列表或集合)是有问题的。但不管怎样,您应该始终使用接口,如
Map<String, Map<String, CustomObject>> maps;
地图;
这对于某些用例来说是可以的,但取决于您想要建模的确切内容(特别是当有另一层时),这可能已经很不方便了。使用3个嵌套的
HashMap
s已经是一个糟糕设计的标志。。你应该考虑创建自己的类来隐藏嵌套的映射。使用一个封装了<代码>字符串和一个<代码> HashMap <代码>的类,然后使用另一个封装前一个的.Maloun我在它周围有一个类(单独的哈希表),但是就像我所说的更新变得昂贵一样。对吗?@ambigram_maker你能再解释一下吗?@shraya在什么意义上是昂贵的?跳过列表比哈希表有什么好处?哈希表不支持这里需要的树结构,而且哈希表同步实现线程安全的所有方法,这非常慢。此外,ConcurrentSkipListMap支持并发编辑,而无需抛出ConcurrentModificationException。你能再详细一点吗?谢谢。树形图是一个树形图,因此,默认情况下,它有一个树的层次结构。好的,但是我仍然不清楚在哪里可以维护层次结构a->A1
和B->B1
。很抱歉,我对树木和大麻还不太熟悉哇,这太全面了。我会花点时间来理解这一点,然后再联系你。但看起来这可能会有所帮助。谢谢你,好心的先生。这就是我要找的。谢谢@Marco13。我从中了解了很多。