TreeMap
由Key, Value
对实例化。对我来说,Key
是一个IP地址,而Value
是包含该IP地址统计信息的对象。
是否有理由在Key
对象中冗余存储Value
?我很想节省空间并将其遗漏,但直观地说,如果没有Key
在对象内部(为了良好的封装)会感觉不对。
答案 0 :(得分:3)
请记住,包含密钥只会将值对象的大小增加32位或64位(取决于您使用的是32位还是64位JVM),因此决定是否包含它可能不会对你的程序的内存消耗产生重大影响 - 因此我会错误地包含它而不是不包括它。
答案 1 :(得分:3)
你的设计存在缺陷 - 你处于“拒绝对象”。
您应该创建一个类来保存详细信息,包括IP地址。
如果您希望快速检索给定IP地址的详细信息,则可以使用IP地址作为密钥将它们存储在Map中。
在某种程度上,这就是你所要求的,因为地图中使用的密钥存储在值对象中。只是通过正确的设计,键已经存储在值中的对象的一部分。
答案 2 :(得分:2)
是否有理由在Key对象中冗余存储Key?
首先,您不会将值存储在值对象的“内部”。相反,值对象将具有对关键对象的引用。因此,您根本不存储冗余副本。 (或者至少,除非你故意复制/克隆关键对象......这将是相当愚蠢的。)
唯一的问题是对值对象中的键的引用是否是“冗余的”。从某种意义上说,它是,但另一方面,冗余可能会简化您的代码......并可能使其在其他地方更有效。我们无法在不查看代码中如何使用这些对象(其他地方)的情况下做出判断。但无论如何它的可能性并没有多大差别;见下文。
我很想节省空间并将其遗漏,但直观地说,如果没有将Key放在对象中(为了良好的封装)会感觉不对。
在没有引用值中的键的空间节省是每个值一个字(32或64位)。即使你有数百万这些对象,这很可能太小而无法担心。实际情况是,对于给定的键+值+映射条目,一个额外的单词可能小于总体每对象空间使用量的5%。 5%不太可能产生显着差异......
封装问题取决于上下文。这实际上取决于封装边界的位置,以及它们的多孔性。封装不是最终目标。它是可用于设计/实现可维护软件的一组“工具”之一。它并不总是正确的工具,它必须得到适当的使用;即清楚地了解它如何帮助(或阻碍)手头的问题。
但是这里有一个想法:您可以将“值”对象设为Map
中的键和值...并使用Comparator
。根据细节,这将允许您完全隐藏封装边界内的IP地址(等)。 (这种方法不适用于HashMap
虽然......)
最后的建议。
您似乎正在做有经验的开发人员认为“过早优化”的事情。这通常是一个坏主意。我的建议是暂时不要担心空间使用情况。
等到应用程序正常运行,您就可以使用真实的输入数据进行基准测试。
基准并查看性能(即内存使用情况)是否可以接受。
如果(并且仅当)它是不可接受的,请分析应用程序以寻找减少内存使用的机会。
实施并重新运行基准,看它是否有所作为。
根据需要重复。
答案 3 :(得分:0)
如果密钥将在应用程序中的任何其他位置使用(如果是值对象),那么将其保留在对象内是个好主意