I am trying to create a List of Integer arrays by taking one integer array and shuffling it a number of times. However, once I shuffle the array, the initial array is also modified since it works by reference! Is there any way I can add a variation of the initial array (which is already resident in the list) without creating a new array please?
Thanks!
Just copy the array using System.arrayCopy then use Collections.shuffle on the original.
Related
I had to sort array to find its Median, but now I need to recover the initial value of array, put it as it was. Is that possible?
You can't do that. Sorting is irreversible. However, you could also add all elements of your original list to a new ArrayList and then sort that list.
List<String> original = ...;
List<String> copy = new ArrayList<>(original);
Collections.sort(copy);
I would not worry about the footprint of the copy. It is a shallow copy, that means that the elements themselves are not copied, but only a new list is created with references to the elements contained in the original list. And that operation is quite fast. I would only worry if the list was very, very big.
Using #McEmperors answer but with arrays
Object[] saved = Arrays.copyOf(old, old.length);
Array.sort(old);
There are several ways to achieve what you want:
copy the array before sorting
int[] unsorted = {2,3,1};
int[] sorted = unsorted.clone();
Arrays.sort(sorted);
//find mean in sorted then proceed with unsorted
create a custom sort function that retains a mapping between the positions.
find the mean without sorting
After some search for copying of multidimensional arrays manipulation in java I found this question: copy a 2d array in java and a downvoted answer suggests using the method in the title. So my questions are:
1) why is it bad? (becuase it looks quick and obvious)
2) is the best way still System.arraycopy each line?
Fundamentally, an array is an object. If you have a multidimensional array and you clone it, you won't get copies of the internal arrays (because they are also array Object(s)). You could use Arrays.copyOf(T[],int). From the linked Javadoc,
Copies the specified array, truncating or padding with nulls (if necessary) so the copy has the specified length. For all indices that are valid in both the original array and the copy, the two arrays will contain identical values. For any indices that are valid in the copy but not the original, the copy will contain null. Such indices will exist if and only if the specified length is greater than that of the original array. The resulting array is of exactly the same class as the original array.
Edit
The above is analogous to System.arraycopy() but also creates shallow copies. If you need to create deep copies of the multidimensional array you would have to iterate over the array clone and create a deep copy for each row.
I want to instantiate an ArrayList of ArrayLists (of a generic type). I have this code:
private ArrayList<ArrayList<GameObject>> toDoFlags;
toDoFlags = new ArrayList<ArrayList<GameObject>>(2);
Am I doing this right? It compiles, but when I look at the ArrayList, it has a size of 0.
You're doing it right. The reason it has zero length is because you haven't added anything to it yet.
The "2" you pass is the initial capacity of the array that backs the ArrayList. But the size() method of the ArrayList doesn't return the initial capacity of its backing array... it returns the number of actual elements in the list.
Customarily, you shouldn't be using the initialCapacity parameter. It's a performance optimization when you have large ArrayLists. By allocating a lot of space explicitly, you save the time it would take to re-allocate as you add more and more items to the list. But in this case you probably don't have an extremely large list.
Also, instead of using an ArrayList of ArrayLists, you should consider writing a class to store your data.
ArrayLists expand as you add to them. The integer capacity argument just sets the initial size of the backing array. Setting the capacity to two doesn't mean that there are two elements in the ArrayList, but rather that two elements can be added to the ArrayList before it has to declare a larger internal array.
How to create an array that extends itself. I don't want to use the classes like ArrayList and Vector etc to do this. Instead i need to generate an array that extends it's size upon adding elements to it. This is question by my teacher.
Say for example, i want an int[] which extends it's size.
For instance, the user want to enter the student IDs into an array. The array has no fixed size since there are no fixed no. of students in this case. When the user says he wants one more, the array's size should be incremented by one.
Any answer is appreciated.
Arrays are fixed in length, you can not increase or decrease the size of array.
What you can do create new array with larger size and copy the values using Arrays#copyOf source array to new destination array.
Note: Arrays#copyOf internally call System.copy which does shallow copy.
Here is a useful link for your teacher, from the docs:
An array is a container object that holds a fixed number of values
of a single type. The length of an array is established when the array
is created. After creation, its length is fixed.
The only option to do that without ArrayList/Vector.. is creating a new array and copying the values to it.
Your description, 'When the user says he wants one more, the array's size should be incremented by one.' is just a pointer array, which is LinkedList in java.
Whatever your teacher says there is no way to resize a array dynamically without creating a new array with edited size. I don't think any language supports this requirement. Just create a new array and copy the existing one.
I think i'll have to re-initialize the array with an incremented size but before that, i think i'll have to copy all those elements into a temporary array and then again copy them into the original array whose size is changed.
If this is correct, my teacher might be looking for this. But that degrades the performance though.
I am getting very frustrated because I cannot seem to figure out why Collections shuffling is not working properly.
Lets say that I am trying to shuffle the randomizer array.
int[] randomizer = new int[] {200,300,212,111,6,2332};
Collections.shuffle(Arrays.asList(randomizer));
For some reason the elements stay sorted exactly the same whether or not I call the shuffle method. Any ideas?
Arrays.asList cannot be used with arrays of primitives. Use this instead:
Integer[] randomizer = new Integer[] {200,300,212,111,6,2332};
Collections.shuffle(Arrays.asList(randomizer));
The same rule applies to most classes in the collections framework, in that you can't use primitive types.
The original code (with int[]) compiled fine, but did not work as intended, because of the behaviour of the variadic method asList: it just makes a one-element list, with the int array as its only member.
Chris' answer is correct.
As i said in a comment on Chris' answer, your underlying array will change appropriately unless the arraylist needs to grow, and the list creates a new one and copies items into it.
You may want to keep a reference to the list and iterate over that after the Arrays.asList call, and not iterate over the array after that, iterate over the List instead.