Related
I want to convert an array double[] to an immutable collection for use in a value object. However, I am dealing with a very large array and I keep getting the error java.lang.OutOfMemoryError: Java heap space.
I am currently using
Collections.unmodifiableList(DoubleStream.of(myArray).boxed().collect(Collectors.toList()));
I think it is because of this my program is running out of memory. Is there a cheaper way to convert double[] to an immutable list?
How about creating your own List<Double>? If you implement AbstractList<Double>, you'd only need to implement two methods for an unmodifiable list:
class MyDoubleList extends AbstractList<Double> implements RandomAccess {
private double[] backingArray;
public MyDoubleList(double[] backingArray) {
this.backingArray = backingArray;
}
#Override
public Double get(int index) {
return backingArray[index];
}
#Override
public int size() {
return backingArray.length;
}
// adding other list methods should be trivial...
}
Usage:
List<Double> list = new MyDoubleList(myBigDoubleArray);
Note that if you change the backing array, the list contents will change as well. To prevent this, you'd usually copy the array passed in, but since copying the array will probably cause an out of memory exception, I didn't do it.
Or if you use Guava, use Doubles.asList(myBigDoubleArray), which does essentially the same thing. Thanks to Joe for the suggestion!
Streams are great for functional programming, and readability but should be avoided when performance is the main concern. They create unnecessary extra objects.
Also surprisingly, arrays of the double primitive types consume more memory than their wrapper class Double arrays (ref: https://www.baeldung.com/java-primitives-vs-objects)
Use a Double object array instead of a double primitive, and then run:
Collection<Double> l = Collections.unmodifiableCollection(Arrays.asList(myArray));
I compared the 2 approaches like this
public static void main(String[] args) {
int len = 1000000;
Double[] myArray = new Double[len];
for (int i = 0; i < len; i++) {
myArray[i] = Math.random();
}
Collection<Double> l = Collections.unmodifiableCollection(Arrays.asList(myArray));
long totalMem = Runtime.getRuntime().totalMemory();
long usedMem = totalMem - Runtime.getRuntime().freeMemory();
System.out.println("totalMem="+humanReadableByteCountBin(totalMem));
System.out.println("usedMem=" + humanReadableByteCountBin(usedMem));
System.out.println("l has " + l.size() + " items ");
}
The stream approach used 48Mb, whereas Arrays.asList with Double uses 28Mb.
This question already has answers here:
How to convert an ArrayList containing Integers to primitive int array?
(19 answers)
Closed 4 years ago.
How can I convert a List<Integer> to int[] in Java?
I'm confused because List.toArray() actually returns an Object[], which can be cast to neither Integer[] nor int[].
Right now I'm using a loop to do so:
int[] toIntArray(List<Integer> list) {
int[] ret = new int[list.size()];
for(int i = 0; i < ret.length; i++)
ret[i] = list.get(i);
return ret;
}
Is there's a better way to do this?
This is similar to the question
How can I convert int[] to Integer[] in Java?.
With streams added in Java 8 we can write code like:
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.
Quick searching in documentation of Stream while looking for methods which return IntStream points us to our solution which is mapToInt(ToIntFunction<? super T> mapper) method. All we need to do is provide a mapping from Integer to int.
Since ToIntFunction is functional interface we can provide its instance via lambda or method reference.
Anyway to convert Integer to int we can use Integer#intValue so inside mapToInt we can write:
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
You can't use 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 Integers.
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
Use:
int[] toIntArray(List<Integer> list) {
int[] ret = new int[list.size()];
int i = 0;
for (Integer e : list)
ret[i++] = e;
return ret;
}
This slight change to your code is to avoid expensive list indexing (since a List is not necessarily an ArrayList, but it could be a linked list, for which random access is expensive).
Here is a Java 8 single line code for this:
public int[] toIntArray(List<Integer> intList){
return intList.stream().mapToInt(Integer::intValue).toArray();
}
If you are simply mapping an Integer to an int then you should consider using parallelism, since your mapping logic does not rely on any variables outside its scope.
int[] arr = list.parallelStream().mapToInt(Integer::intValue).toArray();
Just be aware of this
Note that parallelism is not automatically faster than performing operations serially, although it can be if you have enough data and processor cores. While aggregate operations enable you to more easily implement parallelism, it is still your responsibility to determine if your application is suitable for parallelism.
There are two ways to map Integers to their primitive form:
Via a ToIntFunction.
mapToInt(Integer::intValue)
Via explicit unboxing with lambda expression.
mapToInt(i -> i.intValue())
Via implicit (auto-) unboxing with lambda expression.
mapToInt(i -> i)
Given a list with a null value
List<Integer> list = Arrays.asList(1, 2, null, 4, 5);
Here are three options to handle null:
Filter out the null values before mapping.
int[] arr = list.parallelStream().filter(Objects::nonNull).mapToInt(Integer::intValue).toArray();
Map the null values to a default value.
int[] arr = list.parallelStream().map(i -> i == null ? -1 : i).mapToInt(Integer::intValue).toArray();
Handle null inside the lambda expression.
int[] arr = list.parallelStream().mapToInt(i -> i == null ? -1 : i.intValue()).toArray();
This simple loop is always correct! no bugs
int[] integers = new int[myList.size()];
for (int i = 0; i < integers.length; i++) {
integers[i] = myList.get(i);
}
I've noticed several uses of for loops, but you don't even need anything inside the loop. I mention this only because the original question was trying to find less verbose code.
int[] toArray(List<Integer> list) {
int[] ret = new int[ list.size() ];
int i = 0;
for( Iterator<Integer> it = list.iterator();
it.hasNext();
ret[i++] = it.next() );
return ret;
}
If Java allowed multiple declarations in a for loop the way C++ does, we could go a step further and do for(int i = 0, Iterator it...
In the end though (this part is just my opinion), if you are going to have a helping function or method to do something for you, just set it up and forget about it. It can be a one-liner or ten; if you'll never look at it again you won't know the difference.
There is really no way of "one-lining" what you are trying to do, because toArray returns an Object[] and you cannot cast from Object[] to int[] or Integer[] to int[].
int[] ret = new int[list.size()];
Iterator<Integer> iter = list.iterator();
for (int i=0; iter.hasNext(); i++) {
ret[i] = iter.next();
}
return ret;
Also try Dollar (check this revision):
import static com.humaorie.dollar.Dollar.*
...
List<Integer> source = ...;
int[] ints = $(source).convert().toIntArray();
With Eclipse Collections, you can do the following if you have a list of type java.util.List<Integer>:
List<Integer> integers = Lists.mutable.with(1, 2, 3, 4, 5);
int[] ints = LazyIterate.adapt(integers).collectInt(i -> i).toArray();
Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, ints);
If you already have an Eclipse Collections type like MutableList, you can do the following:
MutableList<Integer> integers = Lists.mutable.with(1, 2, 3, 4, 5);
int[] ints = integers.asLazy().collectInt(i -> i).toArray();
Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, ints);
Note: I am a committer for Eclipse Collections
I would recommend you to use the List<?> skeletal implementation from the Java collections API. It appears to be quite helpful in this particular case:
package mypackage;
import java.util.AbstractList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Test {
// Helper method to convert int arrays into Lists
static List<Integer> intArrayAsList(final int[] a) {
if(a == null)
throw new NullPointerException();
return new AbstractList<Integer>() {
#Override
public Integer get(int i) {
return a[i]; // Autoboxing
}
#Override
public Integer set(int i, Integer val) {
final int old = a[i];
a[i] = val; // Auto-unboxing
return old; // Autoboxing
}
#Override
public int size() {
return a.length;
}
};
}
public static void main(final String[] args) {
int[] a = {1, 2, 3, 4, 5};
Collections.reverse(intArrayAsList(a));
System.out.println(Arrays.toString(a));
}
}
Beware of boxing/unboxing drawbacks.
Using a lambda you could do this (compiles in JDK lambda):
public static void main(String ars[]) {
TransformService transformService = (inputs) -> {
int[] ints = new int[inputs.size()];
int i = 0;
for (Integer element : inputs) {
ints[ i++ ] = element;
}
return ints;
};
List<Integer> inputs = new ArrayList<Integer>(5) { {add(10); add(10);} };
int[] results = transformService.transform(inputs);
}
public interface TransformService {
int[] transform(List<Integer> inputs);
}
This question already has answers here:
How to clone ArrayList and also clone its contents?
(21 answers)
Closed 6 years ago.
I am basically just trying to make a deep copy of ones and zeroes, so I could have used booleans, but I was wondering how to do this in genereal for integers.
private ArrayList<Integer> makeDeepCopyInteger(ArrayList<Integer> a) {
ArrayList<Integer> newA = new ArrayList<>(a.size());
for (int i = 0; i < a.size(); i++) {
int newInt = 0;
if (a.get(i) == 1) {
newInt = 1;
}
newA.add(newInt);
}
return newA;
}
The clone() method is protected by the Integer class, so you cannot call Integer.clone() outside of that class. What you can do instead is create a new Integer.
private ArrayList<Integer> makeDeepCopyInteger(ArrayList<Integer> old){
ArrayList<Integer> copy = new ArrayList<Integer>(old.size());
for(Integer i : old){
copy.add(new Integer(i));
}
return copy;
}
You can test that this works by doing something like:
public static void main (String[] args) throws java.lang.Exception
{
ArrayList<Integer> arr = new ArrayList<>();
for(int i = 0; i<5; i++){
arr.add(new Integer(i));
}
ArrayList<Integer> x = makeDeepCopyInteger(arr);
for(int i = 0; i<x.size(); i++){
if(arr.get(i) == x.get(i)){
System.out.println("Same object");
} else {
System.out.println("Not the same object");
}
}
}
Tests
Integer a = new Integer(1);
Integer b = new Integer(a);
System.out.println(a==b); // true
System.out.println(System.identityHashCode(a) == (System.identityHashCode(b))); // false;
Integer a = new Integer(1);
Integer b = a;
System.out.println(a==b); // true
System.out.println(System.identityHashCode(a) == (System.identityHashCode(b))); // true
So from my testing it seems that to create a new reference for copying to a new array, you should use new Integer(). Integer is an immutable object but that reference changes when the value of Integer changes.
Use streams to copy objects. Easy to read, good for JIT. Following code provides a copy of a list with Integer object copies inside.
private ArrayList<Integer> makeDeepCopyInteger(ArrayList<Integer> a){
return a.stream().map(val -> new Integer(val)).collect(toList());
}
To copy custom objects other than Integer override implement and call clone()
return a.stream().map(MyObjectClass::clone).collect(toList());
Instead of clone you can use serialization to json. E.g. as used in BeanUtils.getCopy(sourceBean) in following java-utils
You could do something like:
public static List<Integer> clone(List<Integer> source) {
return source.stream()
.map( intObj -> new Integer(intObj.intValue()))
.collect(Collectors.toList());
}
Or, more old-fashioned:
public static List<Integer> clone(List<Integer> source) {
List<Integer> newList = new ArrayList<>();
for(Integer intObj : source) {
newList.add(new Integer(intObj.intValue()));
}
return newList;
}
Both of these could be made shorter by taking advantage of auto-boxing / auto-unboxing. But I've made it explicit to make it absolutely clear what's going on.
However, it's a pointless exercise - in fact it's actively wasteful of memory and detrimental to performance. Integer is immutable, so it's better for references to point at the same instance of Integer. Because it's not possible for the Integer to change value, it's impossible to cause any harm by sharing an instance.
This holds true for immutable objects in general, and is the reason they are a good thing.
You are very unlikely, as a beginner, to find a case in which new Integer(...) is a good idea (or even Integer.valueOf(int i), although this one might return a cached instance). If you already have an Integer, use the one you have:
Integer oldVar = ... ;
Integer newVar = oldVar;
Immutability means that will always be OK. It is impossible for an operation on newVar to corrupt oldVar because there is no newVar.setValue(newValue).
If you have an int use it directly and allow Java's auto-boxing to convert it into an Integer:
int oldValue = ... ;
Integer newValue = oldValue ; // Java will automatically put this through
// Integer.valueOf(int i)
You mentioned that you really wanted to work with booleans. You should consider using BitSet.
you'll have to iterate over the items of the list and clone them before, adding them to the new list, as mentioned here:
How to clone ArrayList and also clone its contents?
This question already has answers here:
How can I convert List<Integer> to int[] in Java? [duplicate]
(16 answers)
Closed 9 years ago.
Is there a way, to convert a List of Integers to Array of ints (not integer). Something like List to int []? Without looping through the list and manually converting the intger to int.
You can use the toArray to get an array of Integers, ArrayUtils from the apache commons to convert it to an int[].
List<Integer> integerList = new ArrayList<Integer>();
Integer[] integerArray = integerList.toArray(new Integer[0]);
int[] intArray = ArrayUtils.toPrimitive(integerArray);
Resources :
Apache commons - ArrayUtils.toPrimitive(Integer[])
Apache commons lang
Javadoc - Collection.toArray(T[])
On the same topic :
How to convert List to int[] in Java?
I'm sure you can find something in a third-party library, but I don't believe there's anything built into the Java standard libraries.
I suggest you just write a utility function to do it, unless you need lots of similar functionality (in which case it would be worth finding the relevant 3rd party library). Note that you'll need to work out what to do with a null reference in the list, which clearly can't be represented accurately in the int array.
No :)
You need to iterate through the list. It shouldn't be too painful.
Here is a utility method that converts a Collection of Integers to an array of ints. If the input is null, null is returned. If the input contains any null values, a defensive copy is created, stripping all null values from it. The original collection is left unchanged.
public static int[] toIntArray(final Collection<Integer> data){
int[] result;
// null result for null input
if(data == null){
result = null;
// empty array for empty collection
} else if(data.isEmpty()){
result = new int[0];
} else{
final Collection<Integer> effective;
// if data contains null make defensive copy
// and remove null values
if(data.contains(null)){
effective = new ArrayList<Integer>(data);
while(effective.remove(null)){}
// otherwise use original collection
}else{
effective = data;
}
result = new int[effective.size()];
int offset = 0;
// store values
for(final Integer i : effective){
result[offset++] = i.intValue();
}
}
return result;
}
Update: Guava has a one-liner for this functionality:
int[] array = Ints.toArray(data);
Reference:
Ints.toArray(Collection<Integer>)
List<Integer> listInt = new ArrayList<Integer>();
StringBuffer strBuffer = new StringBuffer();
for(Object o:listInt){
strBuffer.append(o);
}
int [] arrayInt = new int[]{Integer.parseInt(strBuffer.toString())};
I think this should solve your problem
This question already has answers here:
How to convert an ArrayList containing Integers to primitive int array?
(19 answers)
Closed 4 years ago.
How can I convert a List<Integer> to int[] in Java?
I'm confused because List.toArray() actually returns an Object[], which can be cast to neither Integer[] nor int[].
Right now I'm using a loop to do so:
int[] toIntArray(List<Integer> list) {
int[] ret = new int[list.size()];
for(int i = 0; i < ret.length; i++)
ret[i] = list.get(i);
return ret;
}
Is there's a better way to do this?
This is similar to the question
How can I convert int[] to Integer[] in Java?.
With streams added in Java 8 we can write code like:
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.
Quick searching in documentation of Stream while looking for methods which return IntStream points us to our solution which is mapToInt(ToIntFunction<? super T> mapper) method. All we need to do is provide a mapping from Integer to int.
Since ToIntFunction is functional interface we can provide its instance via lambda or method reference.
Anyway to convert Integer to int we can use Integer#intValue so inside mapToInt we can write:
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
You can't use 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 Integers.
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
Use:
int[] toIntArray(List<Integer> list) {
int[] ret = new int[list.size()];
int i = 0;
for (Integer e : list)
ret[i++] = e;
return ret;
}
This slight change to your code is to avoid expensive list indexing (since a List is not necessarily an ArrayList, but it could be a linked list, for which random access is expensive).
Here is a Java 8 single line code for this:
public int[] toIntArray(List<Integer> intList){
return intList.stream().mapToInt(Integer::intValue).toArray();
}
If you are simply mapping an Integer to an int then you should consider using parallelism, since your mapping logic does not rely on any variables outside its scope.
int[] arr = list.parallelStream().mapToInt(Integer::intValue).toArray();
Just be aware of this
Note that parallelism is not automatically faster than performing operations serially, although it can be if you have enough data and processor cores. While aggregate operations enable you to more easily implement parallelism, it is still your responsibility to determine if your application is suitable for parallelism.
There are two ways to map Integers to their primitive form:
Via a ToIntFunction.
mapToInt(Integer::intValue)
Via explicit unboxing with lambda expression.
mapToInt(i -> i.intValue())
Via implicit (auto-) unboxing with lambda expression.
mapToInt(i -> i)
Given a list with a null value
List<Integer> list = Arrays.asList(1, 2, null, 4, 5);
Here are three options to handle null:
Filter out the null values before mapping.
int[] arr = list.parallelStream().filter(Objects::nonNull).mapToInt(Integer::intValue).toArray();
Map the null values to a default value.
int[] arr = list.parallelStream().map(i -> i == null ? -1 : i).mapToInt(Integer::intValue).toArray();
Handle null inside the lambda expression.
int[] arr = list.parallelStream().mapToInt(i -> i == null ? -1 : i.intValue()).toArray();
This simple loop is always correct! no bugs
int[] integers = new int[myList.size()];
for (int i = 0; i < integers.length; i++) {
integers[i] = myList.get(i);
}
I've noticed several uses of for loops, but you don't even need anything inside the loop. I mention this only because the original question was trying to find less verbose code.
int[] toArray(List<Integer> list) {
int[] ret = new int[ list.size() ];
int i = 0;
for( Iterator<Integer> it = list.iterator();
it.hasNext();
ret[i++] = it.next() );
return ret;
}
If Java allowed multiple declarations in a for loop the way C++ does, we could go a step further and do for(int i = 0, Iterator it...
In the end though (this part is just my opinion), if you are going to have a helping function or method to do something for you, just set it up and forget about it. It can be a one-liner or ten; if you'll never look at it again you won't know the difference.
There is really no way of "one-lining" what you are trying to do, because toArray returns an Object[] and you cannot cast from Object[] to int[] or Integer[] to int[].
int[] ret = new int[list.size()];
Iterator<Integer> iter = list.iterator();
for (int i=0; iter.hasNext(); i++) {
ret[i] = iter.next();
}
return ret;
Also try Dollar (check this revision):
import static com.humaorie.dollar.Dollar.*
...
List<Integer> source = ...;
int[] ints = $(source).convert().toIntArray();
With Eclipse Collections, you can do the following if you have a list of type java.util.List<Integer>:
List<Integer> integers = Lists.mutable.with(1, 2, 3, 4, 5);
int[] ints = LazyIterate.adapt(integers).collectInt(i -> i).toArray();
Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, ints);
If you already have an Eclipse Collections type like MutableList, you can do the following:
MutableList<Integer> integers = Lists.mutable.with(1, 2, 3, 4, 5);
int[] ints = integers.asLazy().collectInt(i -> i).toArray();
Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, ints);
Note: I am a committer for Eclipse Collections
I would recommend you to use the List<?> skeletal implementation from the Java collections API. It appears to be quite helpful in this particular case:
package mypackage;
import java.util.AbstractList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Test {
// Helper method to convert int arrays into Lists
static List<Integer> intArrayAsList(final int[] a) {
if(a == null)
throw new NullPointerException();
return new AbstractList<Integer>() {
#Override
public Integer get(int i) {
return a[i]; // Autoboxing
}
#Override
public Integer set(int i, Integer val) {
final int old = a[i];
a[i] = val; // Auto-unboxing
return old; // Autoboxing
}
#Override
public int size() {
return a.length;
}
};
}
public static void main(final String[] args) {
int[] a = {1, 2, 3, 4, 5};
Collections.reverse(intArrayAsList(a));
System.out.println(Arrays.toString(a));
}
}
Beware of boxing/unboxing drawbacks.
Using a lambda you could do this (compiles in JDK lambda):
public static void main(String ars[]) {
TransformService transformService = (inputs) -> {
int[] ints = new int[inputs.size()];
int i = 0;
for (Integer element : inputs) {
ints[ i++ ] = element;
}
return ints;
};
List<Integer> inputs = new ArrayList<Integer>(5) { {add(10); add(10);} };
int[] results = transformService.transform(inputs);
}
public interface TransformService {
int[] transform(List<Integer> inputs);
}