I have an array of int:
int[] a = {1, 2, 3};
I need a typed set from it:
Set<Integer> s;
If I do the following:
s = new HashSet(Arrays.asList(a));
it, of course, thinks I mean:
List<int[]>
whereas I meant:
List<Integer>
This is because int is a primitive. If I had used String, all would work:
Set<String> s = new HashSet<String>(
Arrays.asList(new String[] { "1", "2", "3" }));
How to easily, correctly and succinctly go from:
A) int[] a...
to
B) Integer[] a ...
Thanks!
Using Stream:
// int[] nums = {1,2,3,4,5}
Set<Integer> set = Arrays.stream(nums).boxed().collect(Collectors.toSet())
The question asks two separate questions: converting int[] to Integer[] and creating a HashSet<Integer> from an int[]. Both are easy to do with Java 8 streams:
int[] array = ...
Integer[] boxedArray = IntStream.of(array).boxed().toArray(Integer[]::new);
Set<Integer> set = IntStream.of(array).boxed().collect(Collectors.toSet());
//or if you need a HashSet specifically
HashSet<Integer> hashset = IntStream.of(array).boxed()
.collect(Collectors.toCollection(HashSet::new));
Some further explanation. The asList method has this signature
public static <T> List<T> asList(T... a)
So if you do this:
List<Integer> list = Arrays.asList(1, 2, 3, 4)
or this:
List<Integer> list = Arrays.asList(new Integer[] { 1, 2, 3, 4 })
In these cases, I believe java is able to infer that you want a List back, so it fills in the type parameter, which means it expects Integer parameters to the method call. Since it's able to autobox the values from int to Integer, it's fine.
However, this will not work
List<Integer> list = Arrays.asList(new int[] { 1, 2, 3, 4} )
because primitive to wrapper coercion (ie. int[] to Integer[]) is not built into the language (not sure why they didn't do this, but they didn't).
As a result, each primitive type would have to be handled as it's own overloaded method, which is what the commons package does. ie.
public static List<Integer> asList(int i...);
Or you could easly use Guava to convert int[] to List<Integer>:
Ints.asList(int...)
asList
public static List<Integer> asList(int... backingArray)
Returns a fixed-size list backed by the specified array, similar to Arrays.asList(Object[]). The list supports List.set(int, Object), but any attempt to set a value to null will result in a NullPointerException.
The returned list maintains the values, but not the identities, of Integer objects written to or read from it. For example, whether list.get(0) == list.get(0) is true for the returned list is unspecified.
You can use ArrayUtils in Apache Commons:
int[] intArray = { 1, 2, 3 };
Integer[] integerArray = ArrayUtils.toObject(intArray);
Another option would be to use a primitive set from Eclipse Collections. You can easily convert an int[] to a MutableIntSet to a Set<Integer> or Integer[] as shown below, or you can use the MutableIntSet as is which will be much more memory efficient and performant.
int[] a = {1, 2, 3};
MutableIntSet intSet = IntSets.mutable.with(a);
Set<Integer> integerSet = intSet.collect(i -> i); // auto-boxing
Integer[] integerArray = integerSet.toArray(new Integer[]{});
If you want to go directly from the int array to the Integer array and preserve order, then this will work.
Integer[] integers =
IntLists.mutable.with(a).collect(i -> i).toArray(new Integer[]{});
Note: I am a committer for Eclipse Collections
Just add elements from array to Set with the below snippet
public class RemoveDuplicateElements {
public static void main(String args[]){
int array[] = {0,1,2,3,4,5,6,7,8,9,1,2,3,4,5};
Set <Integer> abc = new HashSet <Integer>();
for (Integer t:array){
abc.add(t);
}
System.out.println("sampleSet"+abc);
}
}
No need for looping :
Just you will convert the array to a List
Then converting this List to a hash set.
Ex:
List list = Arrays.asList(your_array);
Set set = new HashSet<>(list);
This worked perfect for me .
Related
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 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);
}
Given 2 arrays, how can one find out quickly if they are identical by value to each other?
For example, arr1 and arr2 are considered to be identical because they contain equal values, while arr2 and arr3 aren't
int[] arr1 = new int[]{-1, 0, 1};
int[] arr2 = new int[] {-1, 0, 1};
int[] arr3 = new int[] {0, -1, 1}; // not identical
What is the quickest way to find out? I know a for loop will work, but can you do faster, say, constant time? HashSet doesn't work, because technically arr1 and arr2 are different objects
Edit1: what if there are N arrays, and we want to filter out the unique ones?
Arrays.equals will check for content-based equality of two arrays; it is O(n), which is optimal. You can't do better than O(n).
If you want to filter out the unique arrays among n arrays, you might write something like this:
import java.nio.IntBuffer;
int[][] distinctArrays(int[]... arrays) {
Set<IntBuffer> set = new HashSet<>();
for (int[] array : arrays) {
set.add(IntBuffer.wrap(array));
}
int[][] result = new int[set.size()][];
int i = 0;
for (IntBuffer wrappedArray : set) {
result[i++] = wrappedArray.array();
}
return result;
}
...or, with Java 8...
int[][] distinctArrays(int[]... arrays) {
return Stream.of(arrays)
.map(IntBuffer::wrap)
.distinct()
.map(IntBuffer::array)
.toArray(int[][]::new);
}
There's an equals method in the Arrays class, here's the JavaDoc: Arrays.equals
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);
}
int[] arrc = new int[] {1, 2, 3};
System.out.println(new ArrayList(Arrays.asList(arrc)));
prints address, but i desire to use toString as in ArrayList.
Is it possible ?
Try:
import java.util.Arrays;
// ...
int[] arrc = new int[] {1, 2, 3};
System.out.println(Arrays.toString(arrc));
Note that the asList(...) does not take an array of primitive int's but takes Objects instead, that's why you see an address-like String appear.
So, doing:
int[] array = {1, 2, 3};
List list = Arrays.asList(array);
results in the same as doing:
int[] array = {1, 2, 3};
List list = new ArrayList();
list.add(array);
Both result in a List that has one element in it: an array of primitive ints.
(only that Arrays.asList(...) returns a List that cannot be modified...)
If you just want to print the array:
Arrays.toString( arrc )
If you want to turn an int[] into a List, Arrays.asList does not work, unfortunately (it only works with Object[]):
List<Integer> list = new ArrayList<Integer>(arrc.length);
for (int a: arrc)
list.add(a);
System.out.println(list); // prints nicely now
use Arrays.toString(arrc)
Use Apache Commons Lang as your main library after SDK
System.out.println("An object: " + ReflectionToStringBuilder.toString(anObject));
using Dollar should be simple:
int[] ary = { 1, 2, 3, 4};
String string = $(ary).toString(); // wrapping Arrays.toString()
alternatively you can convert the int array to List then use the toString method :
List<Integer> list = $(ary).toList();
please note that list is an ArrayList: you can even specify which concrete class should be used simply passing a List implementation (it will work with any List implementation with a no-args constructor):
List<Integer> linkedList = $(ary).toList(LinkedList.class);
Using Ints.asList from Guava:
import java.util.List;
import com.google.common.primitives.Ints;
// ...
int[] arrc = {1, 2, 3, 4};
List<Integer> list = Ints.asList(arrc);
System.out.println(list);
// Output: "[1, 2, 3, 4]"