我是Java的新手,非常困惑 .
我有一个长度为4 int[]
的大型数据集,我想计算4个整数的每个特定组合出现的次数 . 这与计算文档中的单词频率非常相似 .
我想创建一个 Map<int[], double>
,它将每个int []映射到一个运行计数,因为列表被迭代,但Map不采用原始类型 .
所以我做了 Map<Integer[], Double>
我的数据存储为 ArrayList<int[]>
所以我的循环应该是这样的
ArrayList<int[]> data = ... // load a dataset`
Map<Integer[], Double> frequencies = new HashMap<Integer[], Double>();
for(int[] q : data) {
// **DO SOMETHING TO convert q from int[] to Integer[] so I can put it in the map
if(frequencies.containsKey(q)) {
frequencies.put(q, tfs.get(q) + p);
} else {
frequencies.put(q, p);
}
}
我不确定在评论中需要哪些代码才能使 int[]
转换为 Integer[]
. 或者我可能从根本上对正确的方法感到困惑 .
12 回答
Native Java 8(一行)
使用Java 8,
int[]
可以轻松转换为Integer[]
:正如其他人所说,
Integer[]
通常不是一个好的 Map 键 . 但就转换而言,我们现在拥有一个相对干净的本机代码 .如果要将
int[]
转换为Integer[]
,则无法在JDK中自动执行此操作 . 但是,你可以这样做:如果您有权访问Apache lang库,那么您可以使用ArrayUtils.toObject(int[])方法,如下所示:
据推测,您希望映射的键匹配元素的值而不是数组的标识 . 在这种情况下,您需要某种对象,如您所期望的那样定义
equals
和hashCode
. 最简单的是转换为List<Integer>
,或ArrayList
或更好地使用Arrays.asList
. 更好的是你可以引入一个代表数据的类(类似于java.awt.Rectangle
,但我建议将变量设为私有,最后也是类最终) .使用没有外部库的常规for循环:
Convert int[] to Integer[]:
Convert Integer[] to int[]:
我在之前的回答中错了 . 正确的解决方案是使用此类作为包装实际int []的映射中的键 .
并改变你的代码:
您可以使用IntBuffer来包装现有的int [],而不必将数据复制到Integer数组中,而不是编写自己的代码 .
IntBuffer实现了可比性,因此您可以使用已编写的代码 . 正式映射比较键,使得a.equals(b)用于表示两个键相等,因此两个具有数组1,2,3的IntBuffers - 即使数组位于不同的内存位置 - 也被认为是相同的,因此适合您的频率代码 .
}
希望有所帮助
不确定为什么你需要在你的 Map 中使用Double . 就你要做的事情来说,你有一个int []而你只想要计算每个序列出现的次数?为什么这需要Double呢?
我要做的是使用适当的.equals和.hashCode方法为int数组创建一个包装器,以解释int []对象本身不考虑这些方法的版本中的数据这一事实 .
然后使用google guava的multiset,这意味着计算出现的目的,只要你输入的元素类型有正确的.equals和.hashCode方法 .
然后,获取任何特定组合的计数:
Update: 虽然下面编译,但它会在运行时抛出
ArrayStoreException
. 太糟糕了 . 我会留待以备参考 .将
int[]
转换为Integer[]
:我必须承认,由于
System.arraycopy
处于低水平和一切,但我确实感到有些惊讶,但确实如此 . 至少在java7中 .您可以轻松地转换其他方式 .
这就像一个魅力!
你不需要 .
int[]
是一个对象,可以在 Map 中用作键 .是频率图的正确定义 .
这是错的:-) . 也发布了正确的解决方案:-) .
只需使用: