casting integer array to object array in java - java

I am using JDK 1.6 but the second line in the following snippet gives a compile error in Eclipse:
long[] css = new long[]{1, 2, 3};
Object[] objs = Arrays.copyOf(ccs, ccs.length, Object[].class );
Error is: The method copyOf(long[], int) in the type Arrays is not applicable for the arguments (long[], int, Class)
Casting is required for
org.hibernate.criterion.Restrictions.in("PropertyName", objs );
Any ideas or recommended approach?
TIA.

You can't do that in the java. long is a primitive type, and does because of that not extend Object. Long, which is a wrapper class for long, does and can be cast to an Object. To create a Long[] from a long[] you will need to go through every value of long[] and copy that to Long[]:
long[] primitiveLong;
Long[] wrappedLong = new Long[primitiveLong.length];
for (int i=0; i<primitiveLong.length; i++) {
wrappedLong[i] = primitiveLong[i];
}
Then you can cast it to an array of Object:
Object[] objs = wrappedLong;
Or you can even make the wrappedLong of type Object directly so you don't need the casting.

Use Apache Commons' ArrayUtils.toObject which does exactly this.

Related

For a List<Long> in Java, do you have to cast primitive long into Long before adding it?

If you have List<Long> list, do you have to cast primitive longs to Long?
Do you have to do this
long l = -1;
list.add( (Long) l);
or will
list.add(l);
be fine and not cause any exceptions/errors?
I am assuming your java version is > 1.5 since you used generic list.
So in your case, list.add(l); will work
Don't be afraid to try such things on your local machine.
Read more here: Autoboxing and Unboxing
No you do not, the int primitives will be AutoBoxed
There is no need to cast primitive type long to object wrapper class Long compiler takes care of it. It is called Autoboxing.
As JavaDoc says : Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes. For example, converting an int to an Integer, a double to a Double, and so on. If the conversion goes the other way, this is called unboxing.. Please refer
Consider the following code:
List<Integer> list = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
list.add(i);
Although you add the int values as primitive types, rather than Integer objects, to list, the code compiles. Because list is a list of Integer objects, not a list of int values, you may wonder why the Java compiler does not issue a compile-time error. The compiler does not generate an error because it creates an Integer object from i and adds the object to list. Thus, the compiler converts the previous code to the following at runtime:
List<Integer> list = new ArrayList<>();
for (int i = 1; i < 50; i += 2)
list.add(Integer.valueOf(i));

How to get a array[] out of my LinkedList

I need to convert my List:
List<Double> listFoo = new LinkedList<Double>();
to a array of double. So I tried:
double[] foo = listFoo.toArray();
But I get the error:
Type mismatch: cannot convert from Object[] to double[]
How can I avoid this? I could Iterate over the list and create the array step by step, but I don't want to do it this way.
You need to make, generic one
Double[] foo = listFoo.toArray(new Double[listFoo.size()]);
That would be the fastest way.
Using new Double[listFoo.size()] (with array size) you will reuse that object (generally it is used to make generic invocation of method toArray).
You can't make the array of primitives with the standard List class's toArray() methods. The best you can do is to make a Double[] with the generic method toArray( T[] ).
Double[] foo = listFoo.toArray( new Double[ listFoo.size() ] );
One easy way to make a double[] is to use Guava's Doubles class.
double[] foo = Doubles.toArray( listFoo );
It should work if you make foo an array of Doubles instead of doubles (one is a class, the other a primitive type).

Trying to convert array of ints to a list

I'm trying to convert an array of type int to a List by doing
List<Integer> endingRoutesBusStopsList = Arrays.asList(endingRoutesBusStops);
but for some reason I keep getting an error saying
Type mismatch: cannot convert from List<int[]> to List<Integer>
I don't understand what the issue is.
I know doing
List<int[]> endingRoutesBusStopsList = Arrays.asList(endingRoutesBusStops);
will solve the error, but then I can't use it the way I want.
Anyone have any ideas?
This is caused by the fact that int[] is different from Integer[]. Autoboxing does not work on Arrays.
The issue is because an "int[]" is an Object,
Arrays.asList(T...) gets generic vararg, that it means it treats "int[]" as "Object" (the common superclass for array int[] and Integer is Object)
so that from asList method perspective you don't pass an array of ints, but you pass an object .
In any way you should make implicit convertion from int to wrapper Integer. It is advisable to make it explicitly.
We are missing some more of your code, but in general, let me try and answer with code:
This works:
Integer[] arrayOfInt = { Integer.valueOf(0), Integer.valueOf(1) };
List<Integer> listOfInt = Arrays.asList(arrayOfInt);
This works too because the primitive "1" is autoboxed to an Integer object:
Integer[] arrayOfInt = { 1, 2, 3, 4 };
List<Integer> listOfInt = Arrays.asList(arrayOfInt);
Finally, this won't work because an int[] cannot be autoboxed to Integer[]:
int[] arrayOfInt = { 1, 2, 3, 4 };
List<Integer> listOfInt = Arrays.asList(arrayOfInt);
UPDATE: this comes from way down in the comments in a discussion with #MichaelBorek . This example repeatedly tries the same code either autoboxing or not. The cost of autoboxing seems to be that the code that uses it takes 5 times longer than the one that uses Objects directly.

How to convert an int[] array to a List?

I expected this code to display true:
int[] array = {1, 2};
System.out.println(Arrays.asList(array).contains(1));
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:
Java Tutorial > Classes and Objects > Passing Information to a Method or a Constructor > Varargs
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 int
Ints.asList(int ...) creates a List of Integers from an int array
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.
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)
This
System.out.println(Arrays.asList(array).contains(array));
returns true.
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));
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);
}
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.)
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.
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.
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]);
}

casting Object array to Integer array error

What's wrong with the following code?
Object[] a = new Object[1];
Integer b=1;
a[0]=b;
Integer[] c = (Integer[]) a;
The code has the following error at the last line :
Exception in thread "main" java.lang.ClassCastException:
[Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
Ross, you can use Arrays.copyof() or Arrays.copyOfRange() too.
Integer[] integerArray = Arrays.copyOf(a, a.length, Integer[].class);
Integer[] integerArray = Arrays.copyOfRange(a, 0, a.length, Integer[].class);
Here the reason to hitting an ClassCastException is you can't treat an array of Integer as an array of Object. Integer[] is a subtype of Object[] but Object[] is not a Integer[].
And the following also will not give an ClassCastException.
Object[] a = new Integer[1];
Integer b=1;
a[0]=b;
Integer[] c = (Integer[]) a;
You can't cast an Object array to an Integer array. You have to loop through all elements of a and cast each one individually.
Object[] a = new Object[1];
Integer b=1;
a[0]=b;
Integer[] c = new Integer[a.length];
for(int i = 0; i < a.length; i++)
{
c[i] = (Integer) a[i];
}
Edit: I believe the rationale behind this restriction is that when casting, the JVM wants to ensure type-safety at runtime. Since an array of Objects can be anything besides Integers, the JVM would have to do what the above code is doing anyway (look at each element individually). The language designers decided they didn't want the JVM to do that (I'm not sure why, but I'm sure it's a good reason).
However, you can cast a subtype array to a supertype array (e.g. Integer[] to Object[])!
Or do the following:
...
Integer[] integerArray = new Integer[integerList.size()];
integerList.toArray(integerArray);
return integerArray;
}
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
you try to cast an Array of Object to cast into Array of Integer. You cant do it. This type of downcast is not permitted.
You can make an array of Integer, and after that copy every value of the first array into second array.
When casting is done in Java, Java compiler as well as Java run-time check whether the casting is possible or not and throws errors in case not.
When casting of Object types is involved, the instanceof test should pass in order for the assignment to go through.
In your example it results
Object[] a = new Object[1];
boolean isIntegerArr = a instanceof Integer[]
If you do a sysout of the above line, it would return false;
So trying an instance of check before casting would help.
So, to fix the error, you can either add 'instanceof' check
OR
use following line of code:
(Arrays.asList(a)).toArray(c);
Please do note that the above code would fail, if the Object array contains any entry that is other than Integer.

Categories

Resources