Java 快速原语int多键映射?

Java 快速原语int多键映射?,java,performance,map,multikey,Java,Performance,Map,Multikey,对于我正在进行的一个项目,我尝试在大型数据集上创建一个多维轴心。我有所有我想用作int的键,所以基本上,我想返回一组 int1,int2,int3。。intN->Aggregate1,Aggregate2,聚合体 我不能使用N维数组,因为它可能会变得巨大,而且可能会稀疏。我找了一个宝藏,但他们没有多键地图。ApacheCommons有一个多键映射,但这是针对对象的;这可能会起作用,但似乎不那么有趣,因为int将自动装箱为整数,反之亦然 有人知道基本多键映射实现吗?映射到对象的 或者,有没有人有很

对于我正在进行的一个项目,我尝试在大型数据集上创建一个多维轴心。我有所有我想用作int的键,所以基本上,我想返回一组

int1,int2,int3。。intN->Aggregate1,Aggregate2,聚合体

我不能使用N维数组,因为它可能会变得巨大,而且可能会稀疏。我找了一个宝藏,但他们没有多键地图。ApacheCommons有一个多键映射,但这是针对对象的;这可能会起作用,但似乎不那么有趣,因为int将自动装箱为整数,反之亦然

有人知道基本多键映射实现吗?映射到对象的

或者,有没有人有很好的提示,也许有更好的方法来解决我的问题

[编辑]插入时间不太有趣,我需要查找性能,因为映射将大量用于查找值

[编辑二] 谢谢你的回答。我的实现选择是一个包含int[]的自定义类,该类是不可变的,因此可以在构造时计算hashcode

private static class MultiIntKey
{
    int[] ints;

    private int hashCode;

    MultiIntKey( int[] ints )
    {
        this.ints = ints;
        this.hashCode = Arrays.hashCode( this.ints );
    }

    @Override
    public int hashCode()
    {
        return this.hashCode;
    }

    @Override
    public boolean equals( Object obj )
    {
        if ( this == obj )
        {
            return true;
        }
        if ( obj == null )
        {
            return false;
        }
        if ( this.getClass() != obj.getClass() )
        {
            return false;
        }
        MultiIntKey other = (MultiIntKey) obj;
        if ( this.hashCode != other.hashCode )
        {
            return false;
        }
        if ( !Arrays.equals( this.ints, other.ints ) )
        {
            return false;
        }
        return true;
    }
}
最简单的方法:

转换为JSON/Harnese MongoDB进行搜索 创建包含所有键的自定义类,定义其hashcode&equals方法,并使用映射 最简单的方法:

转换为JSON/Harnese MongoDB进行搜索 创建包含所有键的自定义类,定义其hashcode&equals方法,并使用映射 每个键可以是:

IntBuffer.wrap(new int[] { value1, value2, value3 })
IntBuffer的hashCode、equals和compareTo方法取决于其内容,因此它们将用作HashMap或TreeMap键。从技术上讲,这些方法依赖于缓冲区中的其余元素,因此只需确保从不更改所创建的任何IntBuffers的位置或限制

一个警告是顺序很重要:IntBuffer.wrapnew int[]{1,2}不等于IntBuffer.wrapnew int[]{2,1}。

每个键可以是:

IntBuffer.wrap(new int[] { value1, value2, value3 })
IntBuffer的hashCode、equals和compareTo方法取决于其内容,因此它们将用作HashMap或TreeMap键。从技术上讲,这些方法依赖于缓冲区中的其余元素,因此只需确保从不更改所创建的任何IntBuffers的位置或限制

需要注意的一点是,顺序很重要:IntBuffer.wrapnew int[]{1,2}不等于IntBuffer.wrapnew int[]{2,1}。

int1,int2,int3。。intN==int1+int2+…实习生

所以,所有的键都来自同一个表,通过很少的新对象。每次需要使用intern时,都要将该键作为其动态键。

具有 int1,int2,int3。。intN==int1+int2+…实习生

所以,所有的键都来自同一个表,通过很少的新对象。需要使用intern,每次都要将键作为其动态键

ApacheCommons有一个多键映射,但这是针对对象的;这可能会起作用,但似乎不那么有趣,因为int将自动装箱为整数,反之亦然

当然,在试图避开一个对象时使用N个对象是没有意义的

如果键很小,请考虑将它们打包成单个int或长。 如果他们重复很多,考虑ToToBejExpTrimes使用TROVE4J,可能有更多嵌套。 否则,只需创建一个封装所有int的普通对象。一个对象的开销只有几个字节,与4*N相比还不算太坏。一个映射哈希无论如何都是一个很大的开销。。。 如果你的地图是不可变的,那么选择番石榴的不可变地图。看看番石榴表,它只是二维的,但它可能有助于节省一点

只有当您确定需要进行大量优化时,您才进行了一些基准测试或评测?您不需要一个完全成熟的映射,可以考虑您自己基于int[]的实现,在int[]中您可以按顺序放置所有键。很可能你会发现这不值得,但这是一个很好的锻炼D

ApacheCommons有一个多键映射,但这是针对对象的;这可能会起作用,但似乎不那么有趣,因为int将自动装箱为整数,反之亦然

当然,在试图避开一个对象时使用N个对象是没有意义的

如果键很小,请考虑将它们打包成单个int或长。 如果他们重复很多,考虑ToToBejExpTrimes使用TROVE4J,可能有更多嵌套。 否则,只需创建一个封装所有int的普通对象。一个对象的开销只有几个字节,与4*N相比还不算太坏。一个映射哈希无论如何都是一个很大的开销。。。 如果你的地图是不可变的,那么选择番石榴的不可变地图。看看番石榴表,它只是二维的,但它可能有助于节省一点


只有当您确定需要进行大量优化时,您才进行了一些基准测试或评测?您不需要一个完全成熟的映射,可以考虑您自己基于int[]的实现,在int[]中您可以按顺序放置所有键。很可能你会发现这不值得,但这是一个很好的锻炼D

您可能希望查看SparseArray的源代码,并将其修改为使用多键。您的确切意思是什么

通过多键?多键:我有多个东西组合成一个键。例如,Apache Commons有一个多键映射,其中组合键由对象组成。@AleksG我想你是说Android SparseArray?没有足够的信息来提出一种方法。键的数量是否静态已知?目标最可能的密钥数?按每个维度划分的域/典型映射键基数的大小?您可能希望查看SparseArray的源代码并将其修改为使用多键。多键的确切含义是什么?多键:我有多个东西组合到一个键。例如,Apache Commons有一个多键映射,其中组合键由对象组成。@AleksG我想你是说Android SparseArray?没有足够的信息来提出一种方法。键的数量是否静态已知?目标最可能的密钥数?每个维度的域/典型映射键基数的大小?1。我认为,将查找中的每一组整数转换为字符串会大大降低速度。这可能是解决方案的一部分,尽管我更喜欢远离大量创建对象。@RobAu非常好。听起来你可能需要某种定制的解决方案。我要给你的一条建议是:你已经指出了我的两个建议的低效之处,这是有效的。但在开始运行代码并找出瓶颈所在之前,很难对代码进行优化are@RobAu请注意,与第一个方案相比,单个对象的开销可以忽略不计。如果有人在寻找优化地图,我不会提出任何DB,因为它意味着一个数量级的减速。我认为,将查找中的每一组整数转换为字符串会大大降低速度。这可能是解决方案的一部分,尽管我更喜欢远离大量创建对象。@RobAu非常好。听起来你可能需要某种定制的解决方案。我要给你的一条建议是:你已经指出了我的两个建议的低效之处,这是有效的。但在开始运行代码并找出瓶颈所在之前,很难对代码进行优化are@RobAu请注意,与第一个方案相比,单个对象的开销可以忽略不计。如果有人在寻找优化地图的方法,我不会提出任何DB,因为它意味着一个数量级的减速。啊,有趣的想法:。它仍然是对象创建,但我认为我不能没有它。我的整数的顺序是固定的,因为它应该在一个数组中。@RobAu它可能很简单,但内存开销很大。创建两个对象而不是一个,一个int[]和一个HeapIntBuffer,它本身有两个字段。如果您想保存键入,请使用@Value{int value1;int value2;},这样您就完成了所有不可变的操作,并获得getter、构造函数、equals和hashCode。啊,有趣的想法:。它仍然是对象创建,但我认为我不能没有它。我的整数的顺序是固定的,因为它应该在一个数组中。@RobAu它可能很简单,但内存开销很大。创建两个对象而不是一个,一个int[]和一个HeapIntBuffer,它本身有两个字段。如果您想保存键入,请使用@Value{int value1;int value2;},这样您就完成了所有不可变的操作,并且获得了getter、构造函数、equals和hashCode。字符串选项可以工作,而int1*10等选项肯定不行。想想1,2和30,1-它们将产生相同的键-50。我同意,中途开始键入字符串,然后忘记删除第一部分字符串选项将起作用,int1*10等选项肯定不会。想想1,2和30,1-它们将产生相同的键-50。我同意,中途开始键入字符串,然后忘记删除第一部分