50

I've got a HashSet<Integer> with a bunch of Integers in it. I want to turn it into an array, but calling

hashset.toArray();

returns an Object[]. Is there a better way to cast it to an array of int other than iterating through every element manually? I want to pass the array to

void doSomething(int[] arr)

which won't accept the Object[] array, even if I try casting it like

doSomething((int[]) hashSet.toArray());

8 Answers 8

44

You can create an int[] from any Collection<Integer> (including a HashSet<Integer>) using Java 8 streams:

int[] array = coll.stream().mapToInt(Number::intValue).toArray();

The library is still iterating over the collection (or other stream source) on your behalf, of course.

In addition to being concise and having no external library dependencies, streams also let you go parallel if you have a really big collection to copy.

Sign up to request clarification or add additional context in comments.

1 Comment

A bit more concise: int[] array = coll.stream().mapToInt(x -> x).toArray()
22

Apache's ArrayUtils has this (it still iterates behind the scenes):

doSomething(ArrayUtils.toPrimitive(hashset.toArray()));

They're always a good place to check for things like this.

7 Comments

Automatic +1 for recommending Apache Commons.
@skaffman I'd recommend Apache Commons Lang ... not for this particular problem though ... but anyway, make your move ;)
Actually, it doesn't iterate behind the scenes - it iterates twice. There is an unnecessary Integer[] that slows down the process of creating a primitive array from a collection. Actually, I think the choice to use Integer[] as parameter for toPrimitive(..) instead of Iterable<Integer> is a bit clunky as Arrays.asList(Integer[]) is a much faster operation than collection.toArray(). Hence I won't automatically +1 for recommending apache commons :)
sfussenegger, Apache Commons (what I meant by "it") only iterates once. You're right that the creation of the array requires an iteration.
@sfussenegger actually, the code as written in the answer produces an Object[], so it doesn’t even work. You would need ArrayUtils.toPrimitive(hashset.toArray(new Integer[0])), to make it the inefficient solution that it is supposed to be.
|
10

You can convert a Set<Integer> to Integer[] even without Apache Utils:

Set<Integer> myset = new HashSet<Integer>();
Integer[] array = myset.toArray(new Integer[0]);

However, if you need int[] you have to iterate over the set.

Comments

9

Try this. Using 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();

Comments

5

Note: This answer is outdated, use Stream.mapToInt(..)

public int[] toInt(Set<Integer> set) {
  int[] a = new int[set.size()];
  int i = 0;
  for (Integer val : set) {
    // treat null as 0
    a[i++] = val == null ? 0 : val;
  }
  return a;
}

Now that I wrote the code for you it's not that manual anymore, is it? ;)

5 Comments

It wasn't that writing the code to do it manually was a problem, I was just curious to see if there was a better way to do it.
Well, the essence of my answer was that the only way to avoid writing this code is getting others to write it (but actually that's the case for just about any code) - which you successfully did ;)
Can you put null in a Set<Integer>? If so, this code will NPE. I'm not sure what the original poster would want to do with nulls though. I guess omit them from the resulting array.
@davidsheldon Valid remark. You may put null into a Set<Integer> if the implementation supports it (obviously, yes, but that's what Set's Javadoc defines). HashSet and TreeMap will throw a NPE when trying to add null. Throwing a NPE in case set contains null seems to be the way to go though, of course along with appropriate documentation of this behavior - we all document thoroughly, don't we ;)
Not quiet correct. HashSet allows null and TreeSet will allow null if a custom Comparator which can deal with null has been specified. But it’s true that the best behavior is to just let the code throw a NullPointerException if the set contains null.
4

You can just use Guava's:

Ints.toArray(Collection<? extends Number> collection)

Comments

2

Nope; you've got to iterate over them. Sorry.

4 Comments

It makes sense if you think about it. ints aren't objects, so typecasting one to the other doesn't work.
It seems odd that you can't get an array of ints from a HashSet of Integers though, shouldn't the autoboxing kick in and allow you to do it? It's not like the HashSet contains a mixture of types, they're all Integers so (as far as I can see), it wouldn't be a problem.
Collections can only hold objects (Integers in your case). Thus, it would be odd to have a special method to get an array of ints (corresponding methods would be required for other primitive types). Auto-boxing doesn't help, because that only applies for a single primitive<->object conversion. Keep in mind that the actual class (due to type erasure) is HashSet, not HashSet<Integer> (only a compile-time concept).
@MatthewFlaschen wouldn't type erasure cause the actual class to be HashSet<Object>? -docs.oracle.com/javase/tutorial/java/generics/erasure.html
-4

You could also use the toArray(T[] contents) variant of the toArray() method. Create an empty array of ints of the same size as the HashSet, and then pass it to the toArray() method:

Integer[] myarray = new Integer[hashset.size()];
doSomething(hashset.toArray(myarray));

You'd have to change the doSomething() function to accept an Integer[] array instead of int[]. If that is not feasible, you'd have convert the array of values returned by toArray to int[].

2 Comments

It would help to provide your compile errors so I can tell what's wrong with my code.
Why don't you just try compiling it yourself? Once you see the compile error, I can explain you why it happened.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.