We can use the Stream provided by Java 8 to convert a list of Integer to a primitive integer array in Java. We start by converting given List<Integer> to Stream<Integer> using List. stream() method. Now all we need to do is convert Stream<Integer> to int[] .
No one mentioned yet streams added in Java 8 so here it goes:
int[] example1 = list.stream().mapToInt(i->i).toArray();
// OR
int[] example2 = list.stream().mapToInt(Integer::intValue).toArray();
Thought process:
The simple Stream#toArray
returns an Object[]
array, so it is not what we want. Also, Stream#toArray(IntFunction<A[]> generator)
doesn't do what we want because the generic type A
can't represent the primitive type int
So it would be nice to have some stream which could handle the primitive type int
instead of the wrapper Integer
, because its toArray
method will most likely also return an int[]
array (returning something else like Object[]
or even boxed Integer[]
would be unnatural here). And fortunately Java 8 has such a stream which is IntStream
So now the only thing we need to figure out is how to convert our Stream<Integer>
(which will be returned from list.stream()
) to that shiny IntStream
. Here the Stream#mapToInt(ToIntFunction<? super T> mapper)
method comes to the rescue. All we need to do is pass it a mapping from Integer
to int
.
We could use something like Integer#intValue
which returns an int
as shown below:
mapToInt( (Integer i) -> i.intValue() )
(or some may prefer: mapToInt(Integer::intValue)
.)
But similar code can be generated using unboxing, since the compiler knows that the result of this lambda must be of type int
(the lambda used in mapToInt
is an implementation of the ToIntFunction
interface which expects as body a method of type: int applyAsInt(T value)
which is expected to return an int
).
So we can simply write:
mapToInt((Integer i)->i)
Also, since the Integer
type in (Integer i)
can be inferred by the compiler because List<Integer>#stream()
returns a Stream<Integer>
, we can also skip it which leaves us with
mapToInt(i -> i)
Unfortunately, I don't believe there really is a better way of doing this due to the nature of Java's handling of primitive types, boxing, arrays and generics. In particular:
List<T>.toArray
won't work because there's no conversion from Integer
to int
int
as a type argument for generics, so it would have to be an int
-specific method (or one which used reflection to do nasty trickery).I believe there are libraries which have autogenerated versions of this kind of method for all the primitive types (i.e. there's a template which is copied for each type). It's ugly, but that's the way it is I'm afraid :(
Even though the Arrays
class came out before generics arrived in Java, it would still have to include all the horrible overloads if it were introduced today (assuming you want to use primitive arrays).
In addition to Commons Lang, you can do this with Guava's method Ints.toArray(Collection<Integer> collection)
:
List<Integer> list = ...
int[] ints = Ints.toArray(list);
This saves you having to do the intermediate array conversion that the Commons Lang equivalent requires yourself.
The easiest way to do this is to make use of Apache Commons Lang. It has a handy ArrayUtils class that can do what you want. Use the toPrimitive
method with the overload for an array of Integer
s.
List<Integer> myList;
... assign and fill the list
int[] intArray = ArrayUtils.toPrimitive(myList.toArray(new Integer[myList.size()]));
This way you don't reinvent the wheel. Commons Lang has a great many useful things that Java left out. Above, I chose to create an Integer list of the right size. You can also use a 0-length static Integer array and let Java allocate an array of the right size:
static final Integer[] NO_INTS = new Integer[0];
....
int[] intArray2 = ArrayUtils.toPrimitive(myList.toArray(NO_INTS));
Java 8 has given us an easy way to do this via streams...
Using the collections stream()
function and then mapping to ints, you'll get an IntStream. With the IntStream
we can call toArray() which gives us int []
int [] ints = list.stream().mapToInt(Integer::intValue).toArray();
to int []
to IntStream
int[] toIntArray(List<Integer> list) {
int[] ret = new int[list.size()];
int i = 0;
for (Integer e : list)
ret[i++] = e;
return ret;
}
Slight change to your code to avoid expensive list indexing (since a List is not necessarily an ArrayList, but could be a linked list, for which random access is expensive)
Here is Java 8 single line code for this
public int[] toIntArray(List<Integer> intList){
return intList.stream().mapToInt(Integer::intValue).toArray();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With