Java中的字符串索引集合

Java中的字符串索引集合,java,collections,Java,Collections,使用Java,假设v1.6 我有一个集合,其中唯一索引是字符串,非唯一值是int。 我需要尽可能快地对此集合执行数千次查找 我目前正在使用一个HashMap,但我担心整数到int的装箱/拆箱会使速度变慢 我曾想过使用ArrayList和int[]结合使用 i、 e.而不是: int value = (int) HashMap<String, Integer>.get("key"); int value=(int)HashMap.get(“key”); 我可以 int value

使用Java,假设v1.6

我有一个集合,其中唯一索引是字符串,非唯一值是int。 我需要尽可能快地对此集合执行数千次查找

我目前正在使用一个
HashMap
,但我担心整数到int的装箱/拆箱会使速度变慢

我曾想过使用
ArrayList
int[]
结合使用

i、 e.而不是:

int value = (int) HashMap<String, Integer>.get("key");
int value=(int)HashMap.get(“key”);
我可以

int value = int[ArrayList<String>.indexOf("key")];
int-value=int[ArrayList.indexOf(“key”);
有什么想法吗?有没有更快的方法


p、 我只会构建一次集合,可能会修改一次,但每次我都会知道集合的大小,这样我就可以使用
String[]
而不是
ArrayList
,但我不确定是否有更快的方法来复制索引…

我想HashMap会提供更快的查找速度,但我认为这需要一些基准来正确回答


编辑:此外,不需要装箱,只需要拆开已经存储的对象,这应该非常快,因为在这一步中没有对象分配。因此,我认为这不会给您带来更多的速度,但您应该运行基准测试。

取消装箱很快-不需要分配。装箱可能比较慢,因为它需要分配一个新对象(除非它使用池对象)

你确定你真的有问题吗?在实际证明这是一个重大成功之前,不要使代码复杂化。我很怀疑这是真的

有可用于基本类型的集合库,但我会坚持使用JRE中的普通HashMap,直到您分析并检查这是否导致了问题。如果真的只是数千次的查找,我非常怀疑这是否会成为一个问题。同样,如果您是基于查找而不是基于加法的(即,您获取的次数比添加的次数多),那么装箱成本不会特别显著,只是拆箱,这很便宜

不过,我建议使用
intValue()
而不是强制转换将值转换为
int
——这会让事情变得更清楚(IMO)

编辑:要回答注释中的问题,当集合足够大时,
HashMap.get(key)
将比
ArrayList.indexOf(key)
快。如果你实际上只有五个项目,那么这个列表可能会更快。我想情况并非如此


如果你真的,真的不想装箱/拆箱,试试(TObjectHashMap)。还有一些要考虑的问题,但是我在里面找不到正确的类型。

这里有一个小问题:你可以在列表中有重复的元素。如果你真的想做第二种方式,请考虑使用SET。

话虽如此,您有没有对这两个进行性能测试,看看其中一个是否比另一个快


编辑:当然,最流行的集合类型(HashSet)本身有一个HashMap支持,因此切换到集合可能不是一个明智的改变。

我认为扫描ArrayList以找到与“键”匹配的项将比装箱/取消装箱的速度慢得多。

列表。indexOf
通常会对列表进行线性扫描-O(n)。二进制搜索将在O(logn)中完成此任务。哈希表将在O(1)中完成此操作


内存中有大量的
Integer
对象可能是个问题。但是
String
s(字符串
String
char[]
)也是如此。您可以自己定制DB风格的实现,但我建议先进行基准测试。

不必装箱/取消装箱而获得的任何性能提升都会被需要使用indexOf方法的for循环显著删除

使用HashMap。此外,您不需要(int)强制转换,编译器将为您处理它

数组中只有少量的项就可以了,但是HashMap也是如此


可以快速查找数组的唯一方法(这不是一个真正的建议,因为它有太多的问题)是使用字符串的哈希代码作为数组的索引-但不要考虑这样做!(我之所以提到它,是因为你可能会通过谷歌找到一些谈论它的东西……如果他们不解释为什么它不好,就不要再读了!)

既然你说它确实是一个瓶颈,我建议;特别是,地图看起来与您想要的完全一样。

如果一次和一次构建地图的成本无关紧要,您可能需要查看地图,例如。

地图访问不会对查找进行取消装箱,只有稍后对结果的访问会使其速度变慢

我建议为int引入一个带有getter的小包装器,比如SimpleInt。它保存int而不进行转换。构造函数并不昂贵,而且总体上比整数便宜

public SimpleInt
{
    private final int data;

    public SimpleInt(int i)
    {
        data = i;
    }

    // getter here
    ....
}

让Jon Skeet给出一个与整个问题无关的答案……看来基准测试将是正确测试这一点的唯一方法。我不知道拆箱很便宜。我得做些分析来找出瓶颈。也就是说,基于2的内部结构,它应该是更快的ArrayList.indexOf或HashMap.getSorry,还有一条评论。这是一次重大的打击。我需要每一微秒,我可以在这里:)我管理自己的重复建设的集合。集合不起作用,因为集合需要包含某种形式的键值对