快速原始int多键映射?

时间:2014-09-05 19:04:18

标签: java performance map multikey

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

( int1, int2, int3, .. intN ) -> (Aggregate1, Aggregate2, ... , AggregateM)

我不能使用N维数组,因为它可能变得很大并且可能很稀疏。我看起来像一个Trove,但他们没有多键地图。 Apache commons有一个多键映射,但那是Objects;这可能有用,但似乎不那么有趣,因为int将自动装箱到Integers,反之亦然。

有没有人知道原始的多键地图实现? (那映射到对象?)

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

[edit]插入时间不那么有趣,我需要查找性能,因为地图会被大量用于查找值。

[EDIT2] 感谢所有的答案。我的实现选择是一个包含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;
    }
}

4 个答案:

答案 0 :(得分:4)

  

Apache commons有一个多键映射,但它适用于Objects;这可能会起作用,但似乎不那么有趣,因为整数将自动装入整数,反之亦然。

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

  • 如果您的钥匙很小,请考虑将它们打包成一个intlong
  • 如果他们重复了很多,请考虑TIntObjectMap<TIntObjectMap<Value>>使用trove4j,可能还有更多的嵌套。
  • 否则,只需创建一个封装所有int的普通对象。对象开销是几个字节,与4*N相比并没有那么糟糕。无论如何,地图都有很大的开销......

如果您的地图是不可变的,请转到Guava的ImmutableMap。看看Guava Table,它只是2D,但它可能有助于节省一点。


只有当你确定需要优化很多时(你做过一些基准测试或剖析吗?)你不需要一张完全成熟的地图,想想你的基于某些int[]的自己实现,您可以按顺序放置所有键。很可能你会发现它不值得,但这是一个很好的练习。 :d

答案 1 :(得分:1)

每个密钥可以是:

IntBuffer.wrap(new int[] { value1, value2, value3 })

IntBuffer的hashCode,equals和compareTo方法取决于它的内容,因此它们将用作HashMap或TreeMap键。 (从技术上讲,这些方法取决于缓冲区中的其余元素,因此请确保永远不要更改您创建的任何IntBuffers的位置或限制。)

一点需要注意的是,订单很重要:IntBuffer.wrap(new int[] { 1, 2 })不等于IntBuffer.wrap(new int[] { 2, 1 })

答案 2 :(得分:0)

带有的字符串键 (int1,int2,int3,.. intN)==(int1 +“”int2 +“”..)。intern()

所以来自同一个表的所有键都来自intern所以很少有新对象。每当你想要将密钥作为动态密钥时,需要使用实习生。

答案 3 :(得分:-1)

最简单的方法:

  1. 转换为JSON / Harness MongoDB进行搜索
  2. 创建自定义类以包含所有键,定义其哈希码&amp;等于方法,并使用Map