java integer数组_关于数组:如何在Java中将int []转换为Integer []?

我是Java的新手,非常困惑。

我有一个长度为4 int[]的大型数据集,我想计算次数

每个4个整数的特定组合都会出现。 这与计算文档中的单词频率非常相似。

我想创建一个Map,将列表迭代时将每个int []映射到一个运行计数,但是Map不采用原始类型。

所以我做了Map

我的数据存储为ArrayList,所以我的循环应类似于

ArrayList data = ... // load a dataset`

Map frequencies = new HashMap();

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[]。 也许我从根本上对正确的方法感到困惑。

"我想创建一个Map ...但是Map不会采用原始类型。" 正如下面指出的帖子之一,int []不是原始类型,因此这不是真正的问题。 真正的问题是数组不会重写.equals()来比较元素。 从这种意义上讲,转换为Integer [](如您的标题所述)对您没有帮助。 在上面的代码中,frequency.containsKey(q)仍然无法按预期工作,因为它使用.equals()进行比较。 真正的解决方案是不在这里使用数组。

不想用另一个答案来发送垃圾邮件,但现在值得注意的是有关此问题的文档示例。

本机Java 8(一行)

使用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 you  = Arrays.stream( data ).boxed().collect( Collectors.toList() );

List like = IntStream.of( data ).boxed().collect( Collectors.toList() );

正如其他人所说,Integer[]通常不是一个好的地图密钥。

但就转换而言,我们现在拥有一个相对干净的本机代码。

这就是正确的方法。如果需要将Integer-Array作为列表??,可以编写:Listlist = IntStream.of(q).boxed().collect(Collectors.toList());

转换为Integer[]我实际建议使用以下语法:Integer[] boxed = IntStream.of(unboxed).boxed().toArray();以与@NwDx类似的方式

@JoD。是的,这很有效。但是IntStream.of仍然会调用Arrays.stream。我认为这取决于个人喜好-我更喜欢一个重写的功能,有些喜欢使用更明确的类。

在您的示例中修复toArray的签名,然后我们同意。事实上,我可能更喜欢你的版本。

@JoD。是的,这很难过。但只要流被装箱(即不是IntStream),toArray总是需要一个构造函数,无论源是什么。

不...那是我想说的...它不需要一个...

@JoD。我收到编译错误Object[] cannot be converted to Integer[]。在我的PC和ideone上:ideone.com/uagsSd

@Sheepy:我更喜欢IntStream的用法,因为它与该流中的数据类型更相关。 Arrays类更多地用于操作数组而不是流(即使某些方法创建了流)。因此,如果第三方正在阅读您的代码,则他/她完全知道发生了什么。更具可读性的是:对该int数组进行IntStream处理,将其装箱,然后创建一个数组或收集列表。就像您说的那样:数组从该int数组(什么类型的?)生成流并将其装箱(到什么?)。但这一切都取决于品味。

我在吃我的鞋子。我错了 - 我以为我试过了,但显然没有。 boxed()仅返回类型为Stream的内容,但是toArray仍需要类型化数组生成器以返回正确类型的Array,否则它将为Object[]。我想这也有好处,而且可能没有别的办法。

感谢您对JoD的支持。我从一个数组的参数类型开始,当您使用一个函数处理大多数数组时,它是统一的。但是我只是想我可以在答案中添加两种语法:p @NwDx

@NwDx不知何故我也本能地使用IntStream.of,但我认为Arrays.stream会受到许多人的青睐,因为它的类型中立是由于超载。

@JoD。完全确认。如果一个人不知道他/她不能创建一个整数数组的数据类型,因为你需要创建数据的类型。只有带收集器的无类型列表才有可能。还是我错了?

我们需要考虑在JEP 169中可能不推荐使用显式原始类型的类。

@JoD。我看不到JEP 169在哪里提到了对框式原始类的弃用。此外,它的优先级较低,并且进度不存在。

@NwDx好吧,与Arrays.stream,IntStream.of和其他原始流相比,还需要您了解数据类型。实际上,如果数据类型发生更改,则后者只会导致更多代码更改。

@Sheepy项目Valhalla的一部分。弃用只是我对未来事物的插补。

那是一个疯狂但伟大的解决方案!谢谢!

这可以应用于2D阵列吗?可以int[][] data转换为Integer[][] whatever吗?

@Chetan可以应用于多个维度,但我强烈反对它(更好地使用正确的循环),因为这种方法根本无法扩展:Integer[][] newData = Arrays.stream( data ).map( row -> Arrays.stream( row ).boxed().toArray( Integer[]::new ) ).toArray( Integer[][]::new ) -

这个新语法是什么:Integer[]::new?

@VijayChavda 2014年,Java 8作为lambda的一部分(JSR 335 Part C)引入了称为方法引用的新语法。这表示the"new" method (constructor) of the Integer[] class。

如果要将int[]转换为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);

}

如果您有权访问Apache lang库,则可以使用ArrayUtils.toObject(int[])方法,如下所示:

Integer[] newArray = ArrayUtils.toObject(oldArray);

+1使用ArrayUtils。

多数民众赞成在一个讨厌的方式做一个循环。

这对每个人来说都是完全正常的......我没有看到令人讨厌的部分。

@Dahaka,糟糕的是使用value的迭代器,而索引变量i就在那里。

@Icn,我明白为什么有些人不喜欢这种风格,但是是什么让它如此讨厌以至于变得讨厌呢?

使用番石榴,我更喜欢ListintList = Ints.asList(oldArray);

@icn,@ Dahaka:糟糕的是,因为你已经在使用递增索引变量,所以也不需要使用for-each;尽管它在代码中看起来很漂亮而且很简单,但是在幕后隐藏了不必要的开销。传统的for (int i...)循环在这里会更有效。

使用不带外部库的常规for循环:

将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

}

将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

}

超级machan !!谢谢@ohtph

据推测,您希望映射的键匹配元素的值而不是数组的标识。在那种情况下,您需要某种可以定义equals和hashCode的对象。最简单的是转换为List,ArrayList或更好地使用Arrays.asList。更好的是,您可以引入一个代表数据的类(类似于java.awt.Rectangle,但我建议将变量设置为private final,并将类也设置为final)。

哦,这是一个数组转换问题,反之亦然:stackoverflow.com/questions/564392/

将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;

}

将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;

}

由于自动装箱,这是相当不准确的。在第一个示例中,您可以简单地执行newArray[i] = ids[i];,而在第二个示例中,只需执行newArray[i] = WrapperArray[i] :)

我在先前的回答中错了。正确的解决方案是使用此类作为包装实际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;

}

}

并改变你的代码:

Map freqs = new HashMap();

for (int[] data : datas) {

IntArrayWrapper wrapper = new IntArrayWrapper(data);

if ( freqs.containsKey(wrapper)) {

freqs.put(wrapper, freqs.get(wrapper) + p);

}

freqs.put(wrapper, p);

}

将课程设为班级决赛,然后将田径赛场设为私人决赛。在构造函数(clone)中创建数组的防御副本。只需从Arrays.equals返回值,而不要使用特殊的if语句。 toString会很好。

哦,从构造函数中抛出一个NPE(可能调用clone)以获取空数据,并且不要将其签入hashCode。

是的..但是等号的代码,hashCode是由IDEA :-)生成的。它工作正常。

您可以使用IntBuffer来包装现有的int [],而不必将数据复制到Integer数组中,而不是编写自己的代码。

int[] a = {1,2,3,4};

IntBuffer b = IntBuffer.wrap(a);

IntBuffer实现了可比性,因此您可以使用已编写的代码。正式地映射比较键,以便使用a.equals(b)表示两个键相等,因此,即使数组位于不同的内存位置,两个具有数组1,2,3的IntBuffer也被称为相等,因此适合您的频率代码。

ArrayList data = ... // load a dataset`

Map frequencies = new HashMap();

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);

}

}

希望有所帮助

这就像一个魅力!

int[] mInt = new int[10];

Integer[] mInteger = new Integer[mInt.length];

List wrapper = new AbstractList() {

@Override

public int size() {

return mInt.length;

}

@Override

public Integer get(int i) {

return mInt[i];

}

};

wrapper.toArray(mInteger);

不确定为什么你需要在你的地图中使用Double。就你要做的事情来说,你有一个int []而你只想要计算每个序列出现的次数?为什么这需要Double呢?

我要做的是使用适当的.equals和.hashCode方法为int数组创建包装器,以解决int []对象本身在这些方法的版本中不考虑数据的事实。

public class IntArrayWrapper {

private int values[];

public IntArrayWrapper(int[] values) {

super();

this.values = values;

}

@Override

public int hashCode() {

final int prime = 31;

int result = 1;

result = prime * result + Arrays.hashCode(values);

return result;

}

@Override

public boolean equals(Object obj) {

if (this == obj)

return true;

if (obj == null)

return false;

if (getClass() != obj.getClass())

return false;

IntArrayWrapper other = (IntArrayWrapper) obj;

if (!Arrays.equals(values, other.values))

return false;

return true;

}

}

然后使用google guava的multiset,这意味着计算出现的目的,只要你输入的元素类型有正确的.equals和.hashCode方法。

List list = ...;

HashMultiset multiset = HashMultiset.create();

for (int values[] : list) {

multiset.add(new IntArrayWrapper(values));

}

然后,获取任何特定组合的计数:

int cnt = multiset.count(new IntArrayWrapper(new int[] { 0, 1, 2, 3 }));

此IntArrayWrapper绝对是使用int[]数组作为哈希键的正确方法,但是应该指出的是,这样的类型已经存在……您可以使用它来包装数组,而不仅仅是hashCode和< x10>,它甚至可比。

更新:虽然下面编译,但它会在运行时抛出ArrayStoreException。太糟糕了。我让它留作以后参考。

将int[]转换为Integer[]:

int[] old;

...

Integer[] arr = new Integer[old.length];

System.arraycopy(old, 0, arr, 0, old.length);

我必须承认,考虑到System.arraycopy是低级的,一切都会编译,我对此感到有些惊讶,但是它确实可以。至少在java7中。

您可以轻松地转换其他方式。

当此答案不起作用时,我认为保留此答案"以供参考"没有太大价值。 System.arraycopy()的文档甚至指出,它不能用于此目的。

你不需要。 int[]是一个对象,可以用作地图内的键。

Map frequencies = new HashMap();

是频率图的正确定义。

这是错的:-)。也发布了正确的解决方案:-)。

非常感谢您的回复我先尝试了这个并且编译得很好,但似乎frequencies.containsKey(q)总是假的,即使Ive put两次相同的数组 - 这里有一些故障涉及javas定义与int []相等S'

Map ,Integer>可以更好地工作。

(提示,(new int [0])。equals(new int [0])为false;(new ArrayList ())。equals(new ArrayList ())为true。

不好的主意,因为数组比较是基于引用相等性的。那就是为什么Arrays.equals()存在的原因...

该死的 :-)。我希望我是对的。声明是正确的,但是由于引用相等性的原因,语义是错误的。

只需使用:

public static int[] intArrayToIntegerArray(Integer[] array)

{

int[] g = new int[array.length];

for(int i = 0; i < array.length; i++){

g[i] = array[i];

}

return g;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值