如何将 Java HashSet<Integer> 转换为原始 int 数组?
Posted
技术标签:
【中文标题】如何将 Java HashSet<Integer> 转换为原始 int 数组?【英文标题】:How can I convert a Java HashSet<Integer> to a primitive int array? 【发布时间】:2011-01-27 21:57:26 【问题描述】:我有一个HashSet<Integer>
,里面有一堆Integers
。我想把它变成一个数组,但是调用
hashset.toArray();
返回一个Object[]
。除了手动遍历每个元素之外,有没有更好的方法将其转换为 int
的数组?我想将数组传递给
void doSomething(int[] arr)
它不会接受 Object[] 数组,即使我尝试像
一样投射它doSomething((int[]) hashSet.toArray());
【问题讨论】:
【参考方案1】:Apache 的 ArrayUtils 有这个(它仍然迭代 behind the scenes):
doSomething(ArrayUtils.toPrimitive(hashset.toArray()));
他们总是检查此类事情的好地方。
【讨论】:
自动 +1 推荐 Apache Commons。 @skaffman 我推荐 Apache Commons Lang ...虽然不是针对这个特殊问题...但无论如何,请采取行动;) 实际上,它不会在幕后迭代——它会迭代两次。有一个不必要的Integer[]
会减慢从集合创建原始数组的过程。实际上,我认为选择使用Integer[]
作为toPrimitive(..)
的参数而不是Iterable<Integer>
有点笨拙,因为Arrays.asList(Integer[])
的操作比collection.toArray()
快得多。因此,我不会自动 +1 推荐 apache commons :)
sfussenegger,Apache Commons(我的意思是“它”)只迭代一次。没错,数组的创建需要迭代。
@sfussenegger 实际上,答案中写的代码会产生一个Object[]
,所以它甚至不起作用。您需要ArrayUtils.toPrimitive(hashset.toArray(new Integer[0]))
,使其成为应有的低效解决方案。【参考方案2】:
试试这个。 使用 java 8。
Set<Integer> set = new HashSet<>();
set.add(43);
set.add(423);
set.add(11);
set.add(44);
set.add(56);
set.add(422);
set.add(34);
int[] arr = set.stream().mapToInt(Integer::intValue).toArray();
【讨论】:
【参考方案3】:即使没有 Apache Utils,您也可以将 Set<Integer>
转换为 Integer[]
:
Set<Integer> myset = new HashSet<Integer>();
Integer[] array = myset.toArray(new Integer[0]);
但是,如果您需要 int[]
,则必须遍历该集合。
【讨论】:
【参考方案4】:您可以使用 Java 8 流从任何 Collection<Integer>
(包括 HashSet<Integer>
)创建 int[]
:
int[] array = coll.stream().mapToInt(Number::intValue).toArray();
当然,该库仍在代表您遍历集合(或其他流源)。
除了简洁且没有外部库依赖之外,如果您要复制非常大的集合,流还可以让您并行处理。
【讨论】:
简洁一点:int[] array = coll.stream().mapToInt(x -> x).toArray()【参考方案5】:您还可以使用 toArray() 方法的 toArray(T[] contents) 变体。创建一个与 HashSet 大小相同的空整数数组,然后将其传递给 toArray() 方法:
Integer[] myarray = new Integer[hashset.size()];
doSomething(hashset.toArray(myarray));
您必须更改doSomething()
函数以接受Integer[]
数组而不是int[]
。如果这不可行,您可以将toArray
返回的值数组转换为int[]
。
【讨论】:
这将有助于提供您的编译错误,以便我知道我的代码有什么问题。 为什么不自己编译一下呢?一旦你看到编译错误,我就可以解释它发生的原因。【参考方案6】:你可以只使用 Guava 的:
Ints.toArray(Collection<? extends Number> collection)
【讨论】:
【参考方案7】:public int[] toInt(Set<Integer> set)
int[] a = new int[set.size()];
int i = 0;
for (Integer val : set) a[i++] = val;
return a;
现在我为您编写了代码,它不再是那种手册了,是吗? ;)
【讨论】:
手动编写代码不是问题,我只是想看看是否有更好的方法。 好吧,我的回答的本质是,避免编写此代码的唯一方法是让其他人编写它(但实际上几乎所有代码都是这种情况)——你成功地做到了;) 你能把 null 放在 SetHashSet
允许 null
和 TreeSet
将允许 null
如果已指定可以处理 null
的自定义 Comparator
。但确实,最好的行为是如果集合包含null
,则让代码抛出NullPointerException
。【参考方案8】:
不;你必须遍历它们。对不起。
【讨论】:
仔细想想就明白了。 int 不是对象,因此将一个类型转换为另一个是行不通的。 您无法从整数的 HashSet 中获取整数数组似乎很奇怪,自动装箱不应该启动并允许您这样做吗?这不像 HashSet 包含多种类型,它们都是整数所以(据我所知),这不是问题。 集合只能保存对象(在您的情况下为整数)。因此,有一个特殊的方法来获取一个整数数组是很奇怪的(其他原始类型需要相应的方法)。自动装箱没有帮助,因为这只适用于单个原始对象转换。请记住,实际的类(由于类型擦除)是 HashSet,而不是 HashSet以上是关于如何将 Java HashSet<Integer> 转换为原始 int 数组?的主要内容,如果未能解决你的问题,请参考以下文章
java:Set对象TreeSet有序子类,HashSet无序子类,重复对象二
java treeset和hashset如何判断元素是不是相同
Java 中 HashSet 的 removeAll 性能分析