I have the following Java code:
import java.util.Arrays;
import java.util.Collections;
public class Test {
public static void main(String[] args) {
int[] test = {1,2,3,4,5};
Collections.rotate(Arrays.asList(test), -1);
for(int i = 0; i < test.length; i++) { System.out.println(test[i]); }
}
}
I want the array to be rotated, but the output I get is
1
2
3
4
5
Why is this?
And is there an alternative solution?
EDIT:
So this works:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Test {
public static void main(String[] args) {
int[] test = {1,2,3,4,5};
List<Integer> testList = new ArrayList<Integer>();
for(int i = 0; i < test.length; i++) { testList.add(test[i]); }
Collections.rotate(testList, -1);
for(int i = 0; i < test.length; i++) { System.out.println(testList.get(i)); }
}
}
But Arrays.asList is supposed to return a list that when written to, copies the changes to the array. Is there any way to fix this without manually doing the conversion from array to list?
I (think that I) can't afford to waste that much CPU time and memory to do the conversion.
Collections class. It is used to rotate the elements present in the specified list of Collection by a given distance. Syntax: public static void rotate(List< type > list, int distance) Parameters : list - the list to be rotated. distance - the distance to rotate the list.
The array can be left rotated by shifting its elements to a position prior to them which can be accomplished by looping through the array and perform the operation arr[j] = arr[j+1]. The first element of the array will be added to the last of rotated array.
This is a tricky problem: yes, asList
backs the List
it returns with the array, and changes to the List
will "write-through" to the array. However, due to how varargs of T...
interacts with an array of primitive type in this case, you're actually creating a list with 1 element!
int[] test = {1,2,3,4,5};
System.out.println(Arrays.asList(test).size());
// prints "1"
Let's try something different:
int[] test = {1,2,3,4,5};
List<Integer> list = Arrays.asList(test);
// "Type mismatch: cannot convert from List<int[]> to List<Integer>"
As you see, the varargs with an int[]
doesn't work the way you intended, and the compiler gives an error. Arrays.asList
actually returns a 1-element List<int[]>
instead of a 5-element List<Integer>
.
Using Integer[]
instead of int[]
works as expected:
Integer[] test = {1,2,3,4,5};
Collections.rotate(Arrays.asList(test), -1);
System.out.println(Arrays.toString(test));
// prints "[2, 3, 4, 5, 1]"
The full signature of asList
is <T> List<T> Arrays.asList(T... a)
. Note that T
can't be int
in this case, for the same reason why you can't have a List<int>
in Java: T
needs to be a reference type.
Consider the following snippet:
System.out.println(Arrays.asList(1,2,3));
// prints "[1, 2, 3]"
What happens here is that each int
is boxed into an Integer
, and the varargs mechanism "works" and asList
creates a list of 3 elements. Now consider the following form instead:
System.out.println(Arrays.asList(new int[] { 1,2,3 }));
// prints "[[I@xxxxxx]"
Now the argument to asList
is an int[]
. T
can't be an int
, therefore, the T...
varargs mechanism "fails", and asList
only gets one element, and it's an int[]
, instead of the int
values themselves.
Now consider this form:
System.out.println(Arrays.asList(new Integer[] { 1,2,3 }));
// prints "[1, 2, 3]"
Now since Integer[]
is a T...
, asList
gets 3 elements as expected.
int[]
does not autobox to an Integer[]
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