Reputation: 12459
I expected this code to display true
:
int[] array = {1, 2};
System.out.println(Arrays.asList(array).contains(1));
Upvotes: 21
Views: 12023
Reputation: 6686
If you're open to using a third-party library, the following options are possible using Eclipse Collections. Both primitive IntList
and boxed List<Integer>
can be used to solve the problem depending on what you require. The lists can also either be mutable or immutable, again based on your requirements.
@Test
public void intArrayToList()
{
int[] array = {1, 2};
// Creates an Eclipse Collections MutableIntList from the int[]
MutableIntList mutableIntList = IntLists.mutable.with(array);
// Creates an Eclipse Collections ImmutableIntList from the int[]
ImmutableIntList immutableIntList = IntLists.immutable.with(array);
IntList expectedIntList = IntLists.immutable.with(1, 2);
Assertions.assertTrue(mutableIntList.contains(1));
Assertions.assertEquals(expectedIntList, mutableIntList);
Assertions.assertTrue(immutableIntList.contains(1));
Assertions.assertEquals(expectedIntList, immutableIntList);
// Converts the MutableIntList to a MutableList<Integer>
// Boxes the int values as Integer objects
MutableList<Integer> mutableList = mutableIntList.collect(i -> i);
// Converts the ImmutableIntList to an ImmutableList<Integer>
// Boxes the int values as Integer objects
ImmutableList<Integer> immutableList = immutableIntList.collect(i -> i);
List<Integer> expectedList = List.of(1, 2);
Assertions.assertTrue(mutableList.contains(1));
Assertions.assertEquals(expectedList, mutableList);
Assertions.assertTrue(immutableList.contains(1));
Assertions.assertEquals(expectedList, immutableList);
}
MutableIntList
and ImmutableIntList
will hold onto a primitive int[]
so there will be no boxing of int
values to Integer
. MutableList<Integer>
and ImmutableList<Integer>
will hold onto boxed Integer
values.
Note: I am a committer for Eclipse Collections.
Upvotes: 0
Reputation: 16216
How to convert an int[] array to a List?
Direct answer using modern Java features:
int[] array = {1, 2};
List<Integer> list = IntStream.of(array).boxed().toList();
System.out.println(list.contains(1)); // true
Note: toList()
is available since Java 16.
An alternative since Java 8 would be collect(Collectors.toList())
.
Upvotes: 2
Reputation: 298838
The method Arrays.asList(T ...)
is, when generics are erased and varargs are transformed, actually equal to a method of type Arrays.ofList(Object[])
(which is the, binary equivalent, JDK 1.4 version of the same Method).
An array of primitives is an Object
(see also this question), but not an Object[]
, so the compiler thinks you are using the varargs version and generates an Object array around your int array. You could illustrate what's happening by adding an extra step:
int[] array = {1, 2};
List<int[]> listOfArrays = Arrays.asList(array);
System.out.println(listOfArrays.contains(1));
This compiles and is equivalent to your code. It also obviously returns false.
The compiler translates varargs calls into calls with a single array, so calling a varargs method that expects parameters T ...
with parameters T t1, T t2, T t3
is equivalent to calling it with new T[]{t1, t2, t3}
but the special case here is that varargs with primitives will be autoboxed before the array is created if the method needs an object array. So the compiler thinks the int array is passed in as a single Object and creates a single element array of type Object[]
, which it passes to asList()
.
So here's the above code once again, the way the compiler implements it internally:
int[] array = {1, 2};
// no generics because of type erasure
List listOfArrays = Arrays.asList(new Object[]{array});
System.out.println(listOfArrays.contains(1));
Here are some good and bad ways to call Arrays.asList()
with int values:
// These versions use autoboxing (which is potentially evil),
// but they are simple and readable
// ints are boxed to Integers, then wrapped in an Object[]
List<Integer> good1 = Arrays.asList(1,2,3);
// here we create an Integer[] array, and fill it with boxed ints
List<Integer> good2 = Arrays.asList(new Integer[]{1,2,3});
// These versions don't use autoboxing,
// but they are very verbose and not at all readable:
// this is awful, don't use Integer constructors
List<Integer> ugly1 = Arrays.asList(
new Integer(1),new Integer(2),new Integer(3)
);
// this is slightly better (it uses the cached pool of Integers),
// but it's still much too verbose
List<Integer> ugly2 = Arrays.asList(
Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3)
);
// And these versions produce compile errors:
// compile error, type is List<int[]>
List<Integer> bad1 = Arrays.asList(new int[]{1,2,3});
// compile error, type is List<Object>
List<Integer> bad2 = Arrays.asList(new Object[]{1,2,3});
Reference:
Arrays.asList(T ...)
But to actually solve your problem in a simple way:
There are some library solutions in Apache Commons / Lang (see Bozho's answer) and in Google Guava:
Ints.contains(int[], int)
checks whether an array of ints contains a given intInts.asList(int ...)
creates a List of Integers from an int arrayUpvotes: 37
Reputation: 9891
The following code displays true:
Integer[] array = {1, 2};
System.out.println(Arrays.asList(array).contains(1));
(Your version fails, since Int's not beeing objects, but Int[] is an object. Therefor you will call asList(T... a) with one element beeing a Collection, since it is not possible to have an Collection a.)
Upvotes: 1
Reputation: 115328
If you only want to check whether the array contains certain element just iterate over array and search for element. This will take o(n/2). All other solutions are less effective. Any method that copies array to list must iterate over array and therefore this operation only requires n atomic assignments.
Upvotes: 0
Reputation: 274562
Autoboxing just doesn't work the way you want it to in this case. The following code may be a bit verbose, but does the job of converting an int array to a list:
List<Integer> list = new ArrayList<Integer>(array.length);
for (int value : array) {
list.add(value);
}
Upvotes: 1
Reputation: 18435
It seems like your understanding of Arrays.asList(T... a)
is wrong. You wouldn't be the first person to make an assumption as to how it works.
Try it with
System.out.println(Arrays.asList(1, 2).contains(1));
Upvotes: 1
Reputation: 597076
Arrays.asList(ArrayUtils.toObjectArray(array))
(ArrayUtils
is from commons-lang)
But if you want to just call contains
there is no need of that. Simply use Arrays.binarySearch(..)
(sort the array first)
Upvotes: 5
Reputation: 413720
When you call
Arrays.asList(array)
on your array of primitives, you get a List instance containing one object: an array of int values! You have to first convert the array of primitives into an array of objects, as @Bozho suggests in his answer.
Upvotes: 0
Reputation: 64632
This
System.out.println(Arrays.asList(array).contains(array));
returns true
.
Upvotes: 1
Reputation: 420951
The Arrays.asList(array)
will result in a singleton list of an int[]
.
It works as you expect if you change int[]
to Integer[]
. Don't know if that helps you though.
Upvotes: 15
Reputation: 2141
I dont think there is a method call you could use. Try it like this
List<Integer> list = new ArrayList<Integer>();
for (int index = 0; index < array.length; index++)
{
list.add(array[index]);
}
Upvotes: -1