1

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

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

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

有谁知道原始的多键映射实现?(映射到对象?)

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

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

[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

4 回答 4

4

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

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

  • 如果您的密钥很小,请考虑将它们打包成一个intlong.
  • 如果它们重复很多,请考虑TIntObjectMap<TIntObjectMap<Value>>使用 trove4j,可能有更多嵌套。
  • 否则,只需创建一个封装所有整数的普通对象。一个对象开销是几个字节,与4*N. 无论如何,地图散列的开销很大......

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


仅当您确定需要进行很多优化(您是否进行了一些基准测试或分析?)并且您不需要完全成熟的地图时,请考虑基于 some 自己的实现int[],您可以在其中按顺序放置所有键. 很可能你会发现它不值得,但这是一个很好的练习。:D

于 2014-09-05T19:56:36.323 回答
1

每个键可以是:

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

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

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

于 2014-09-05T19:26:08.790 回答
0

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

所以通过实习生来自同一张表的所有键 很少有新对象。每次要使用intern都需要key作为它的动态。

于 2014-09-05T19:52:27.177 回答
-1

最简单的方法:

  1. 转换为 JSON / Harness MongoDB 进行搜索
  2. 创建自定义类以包含所有键,定义其 hashcode & equals 方法,并使用 Map
于 2014-09-05T19:09:41.343 回答