收集自己的数据类型或HashMap

时间:2011-10-17 14:13:40

标签: java collections hashmap

我必须将信息存储到数据结构中“Person”类型的对象。该信息可以是例如简单的整数值。整数值将经常变化,并且存储信息的人也可以改变。有两件事很重要:

  1. 如果存在为特定人员存储的信息,应该可以快速查找。
  2. 我必须拥有大量此类数据结构,因此内存非常重要。
  3. 我可以想到两种不同的方式。首先,我当然可以创建一个自己的数据类型,既​​有对人的引用,也有作为字段的整数。问题:我想每次我想知道是否有特定人的信息时,我都要查看所有对象并为该人调用getter-method。其次,我可以使用HashMap,其中Person为键,Integer为Value。从面向对象的角度来看,这可能不如第一种可能性那么优雅。此外,更糟糕的是,HashMaps似乎比简单的集合消耗更多的内存(除此之外,我非常喜欢它们,似乎经常需要链接两个不同的对象)。如果每个例如KB都比我已经存在问题(我可能需要大约一百万次描述的数据结构)。

    您会建议哪种变体?或者你能想到第三种更好的可能性吗?

    谢谢和亲切的问候

    帕特里克

2 个答案:

答案 0 :(得分:1)

一个1KB的人物对我来说似乎有点陡峭。您需要大约256个int字段才能达到该大小。

至于HashMap,我认为这是一个非常好的解决方案,虽然我会使用Person作为值,并使用一些整数或字符串标识符作为键。

从快速查看源代码(忽略地图对象本身的大小),每个map Entry对象都有一个int和3个引用,因此在32位VM上是16个字节;如果Person对象中有20个int字段(80个字节),而int作为键,则Entry + Person + int键的总内存大约为100个字节。 在这些条件下,你需要大约100Mb,一百万人拥有20个int字段(是否太多了?)

至于信息本身,你可以做一些优化:

  • 也许一个字节足以满足一个人的年龄(遗憾的是我们没有超过127岁:P)。考虑一下您需要的数据的值,以及字节或短数是否足够。
  • 如果您需要一个人的名字,而不是将其保留为单个字符串,请考虑使用各种名称的String [],这样您就可以利用String常量池和任何重复的单个名称在jvm中只有一个实例。
  • 虽然情况并非总是这样(它取决于jvm实现),但大多数情况下布尔值是32位,所以如果你真的按内存并且你有很多布尔字段,那么使用一个字节或短场和位掩盖它。你可以获得一个字节的8个“布尔”和一个短的16个。

但请注意,这些优化可能甚至不是必需的,它们肯定会影响代码的可读性。最后,最好的方法可能是运行一些测试并根据需要进行优化。

答案 1 :(得分:0)

我不确定为什么你认为HashMap不像你写的那么优雅(但我不知道你的编程技巧有多么惊人)。也许你的意思是HashMap有更多的方法而不是你需要的。 HashMaps专为快速查找和内存效率而设计(与优先考虑可排序性的TreeMaps相反)。关于内存效率,您是否检查过内存增长情况?与其他非散列映射相比,HashMaps可能看起来像内存猪一样,但与其他非散列映射相比,内存使用量增长非常缓慢(从小开始但变大和快速)。每个条目的KB似乎有点大(这就是为什么我认为当你用足够的样本测量时你会发现真正的大小要小得多),但是再一次,也许不是,而且一百万个条目意味着1 MB - 真的,这有点担心吗?