对于我正在研究的项目,我尝试在大型数据集上创建一个多维轴。我有我想要用作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;
}
}
答案 0 :(得分:4)
Apache commons有一个多键映射,但它适用于Objects;这可能会起作用,但似乎不那么有趣,因为整数将自动装入整数,反之亦然。
当然,在试图避开一个对象时使用N
对象是没有意义的。
int
或long
。TIntObjectMap<TIntObjectMap<Value>>
使用trove4j,可能还有更多的嵌套。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)
最简单的方法: