148 java arrays generics collections
我是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);
}
}
Run Code Online (Sandbox Code Playgroud)
我不确定在评论中需要哪些代码才能使这项工作转换int[]为Integer[].或者我可能从根本上对正确的方法感到困惑.
She*_*epy 158
使用Java 8,int[]可以Integer[]轻松转换为:
int[] data = {1,2,3,4,5,6,7,8,9,10};
// To boxed array
Integer[] what = Arrays.stream( data ).boxed().toArray( Integer[]::new );
Integer[] ever = IntStream.of( data ).boxed().toArray( Integer[]::new );
// To boxed list
List<Integer> you = Arrays.stream( data ).boxed().collect( Collectors.toList() );
List<Integer> like = IntStream.of( data ).boxed().collect( Collectors.toList() );
Run Code Online (Sandbox Code Playgroud)
正如其他人所说,Integer[]通常不是一个好的地图键.但就转换而言,我们现在拥有一个相对干净的本机代码.
Edd*_*die 77
如果要将an转换int[]为an Integer[],则无法在JDK中自动执行此操作.但是,你可以这样做:
int[] oldArray;
... // Here you would assign and fill oldArray
Integer[] newArray = new Integer[oldArray.length];
int i = 0;
for (int value : oldArray) {
newArray[i++] = Integer.valueOf(value);
}
Run Code Online (Sandbox Code Playgroud)
如果您可以访问Apache lang库,那么您可以使用如下ArrayUtils.toObject(int[])方法:
Integer[] newArray = ArrayUtils.toObject(oldArray);
Run Code Online (Sandbox Code Playgroud)
将 int[] 转换为 Integer[]:
import java.util.Arrays;
...
int[] aint = {1,2,3,4,5,6,7,8,9,10};
Integer[] aInt = new Integer[aint.length];
Arrays.setAll(aInt, i -> aint[i]);
Run Code Online (Sandbox Code Playgroud)
据推测,您希望映射的键匹配元素的值而不是数组的标识.在这种情况下,你想要某种对象,定义的equals和hashCode你所期望的.最简单的就是转换为List<Integer>,无论是一个ArrayList或更好地利用Arrays.asList.更好的是你可以引入一个代表数据的类(类似于java.awt.Rectangle但我建议将变量设为私有,最后也是类最终).
将int []转换为Integer []:
int[] primitiveArray = {1, 2, 3, 4, 5};
Integer[] objectArray = new Integer[primitiveArray.length];
for(int ctr = 0; ctr < primitiveArray.length; ctr++) {
objectArray[ctr] = Integer.valueOf(primitiveArray[ctr]); // returns Integer value
}
Run Code Online (Sandbox Code Playgroud)
将Integer []转换为int []:
Integer[] objectArray = {1, 2, 3, 4, 5};
int[] primitiveArray = new int[objectArray.length];
for(int ctr = 0; ctr < objectArray.length; ctr++) {
primitiveArray[ctr] = objectArray[ctr].intValue(); // returns int value
}
Run Code Online (Sandbox Code Playgroud)
我在之前的回答中错了.正确的解决方案是使用此类作为包装实际int []的映射中的键.
public class IntArrayWrapper {
int[] data;
public IntArrayWrapper(int[] data) {
this.data = data;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
IntArrayWrapper that = (IntArrayWrapper) o;
if (!Arrays.equals(data, that.data)) return false;
return true;
}
@Override
public int hashCode() {
return data != null ? Arrays.hashCode(data) : 0;
}
}
Run Code Online (Sandbox Code Playgroud)
并改变你的代码:
Map<IntArrayWrapper, Double > freqs = new HashMap<IntArrayWrapper, Double>();
for (int[] data : datas) {
IntArrayWrapper wrapper = new IntArrayWrapper(data);
if ( freqs.containsKey(wrapper)) {
freqs.put(wrapper, freqs.get(wrapper) + p);
}
freqs.put(wrapper, p);
}
Run Code Online (Sandbox Code Playgroud)
将int []转换为Integer []
public static Integer[] toConvertInteger(int[] ids) {
Integer[] newArray = new Integer[ids.length];
for (int i = 0; i < ids.length; i++) {
newArray[i] = Integer.valueOf(ids[i]);
}
return newArray;
}
Run Code Online (Sandbox Code Playgroud)将Integer []转换为int []
public static int[] toint(Integer[] WrapperArray) {
int[] newArray = new int[WrapperArray.length];
for (int i = 0; i < WrapperArray.length; i++) {
newArray[i] = WrapperArray[i].intValue();
}
return newArray;
}
Run Code Online (Sandbox Code Playgroud)您可以使用 IntBuffer 来包装现有的 int[],而不必编写自己的代码,而无需将数据复制到 Integer 数组中:
int[] a = {1, 2, 3, 4};
IntBuffer b = IntBuffer.wrap(a);
Run Code Online (Sandbox Code Playgroud)
IntBuffer 实现了可比较的,因此您可以使用已经编写的代码。形式上,映射比较键,这样 a.equals(b) 用于表示两个键相等,因此两个具有数组 1,2,3 的 IntBuffer - 即使数组位于不同的内存位置 - 也被认为是相等的,所以将适用于您的频率代码。
ArrayList<int[]> data = ... // Load a dataset`
Map<IntBuffer, Double> frequencies = new HashMap<IntBuffer, Double>();
for(int[] a : data) {
IntBuffer q = IntBuffer.wrap(a);
if(frequencies.containsKey(q)) {
frequencies.put(q, tfs.get(q) + p);
} else {
frequencies.put(q, p);
}
}
Run Code Online (Sandbox Code Playgroud)
Mih*_*der -6
你不需要它。int[]是一个对象,可以用作地图内的键。
Map<int[], Double> frequencies = new HashMap<int[], Double>();
Run Code Online (Sandbox Code Playgroud)
是频率图的正确定义。
这是错误的:-)。正确的解决方案也已发布:-)。
| 归档时间: |
|
| 查看次数: |
159066 次 |
| 最近记录: |