I have a 2D array and I want to grow it. I have copied it into a new array but how do I fill it with the contents from the previous array?
if (row == data.length) {
newData = Arrays.copyOf(data, 2 * data.length);
}
Are you trying to grow it, and then continue manipulating it in later stages of your code?
For example:
You have an array of size 4, you put 0 1 2 3 in it, now it's full, you want to double the size, and then continue adding numbers like 7 8 9 in it.
If that's the case all you need to do is assign newData to your previous array name, which by the example above is 'data'.
if (row == data.length)
{
newData = Arrays.copyOf(data, 2*data.length);
data = newData; //assigns the newArray to the previous variable name
}
If on the other hand you mentioned you wanted a 2D array. Which is an array of arrays of a certain type, then your code should work for 2D arrays too.
There will however be null values in the newly created array slots (eg you have a 2D array of ComplexNumber classes, and if you try to access those classes and call a method like GetImaginaryValue()) you will get a null exception.
As the xscanpix mentioned, your code works, if what we assume you to do is right. Please edit your question if it's not the case.
If it's not what you're looking for I apologize for misunderstanding. I'm going off by the rep you have that you're a new user to SO (like me) and might just be getting started on Java.
How is this code not doing what you want it to do? The java API doc for Arrays.copyOf states that it returns:
'a copy of the original array, truncated or padded with nulls to obtain the specified length' (depends on the type of array)
Edit:
Please post more code or it will be hard to give a reasonable answer.
What does this sentence mean?
"I have copied it into a new array but how do I fill it with the contents from the previous array"
You can try following line to realize this task. dataStart corresponds to the starting position in the source array and newDataStart corresponds to the starting position in the destination array.
System.arraycopy(data, dataStart, newData, newDataStart, data.length);
If you need to extend your array dynamically, you may take a look at ArrayList or Vector.
Related
Hello I am research about that, but I cannot found anything in the oracle website.
The question is the next.
If you are using an static Array like this
int[] foo = new int[10];
And you want add some value to the 4 position of this ways
foor[4] = 4;
That don't shift the elements of the array so the time complexity will be O(1) because if you array start at 0x000001, and have 10 spaces, and you want put some in the x position you can access by (x*sizeOf(int))+initialMemoryPosition (this is a pseudocode)
Is this right, is this the way of that this type of array works in java, and if its time complexity O(1)
Thanks
The question is based on a misconception: in Java, you can't add elements to an array.
An array gets allocated once, initially, with a predefined number of entries. It is not possible to change that number later on.
In other words:
int a[] = new int[5];
a[4] = 5;
doesn't add anything. It just sets a value in memory.
So, if at all, we could say that we have somehow "O(1)" for accessing an address in memory, as nothing related to arrays depends on the number of entries.
Note: if you ask about ArrayList, things are different, as here adding to the end of the array can cause the creation of a new, larger (underlying) array, and moving of data.
An array is somewhere in memory. You don’t have control where, and you should not care where it is. The array is initialized when using the new type[size] syntax is used.
Accessing the array is done using the [] index operator. It will never modify size or order. Just the indexed location if you assign to it.
See also https://www.w3schools.com/java/java_arrays.asp
The time complexity is already correctly commented on. But that is the concern after getting the syntax right.
An old post regarding time complexity of collections can be found here.
Yes, it takes O(1) time. When you initialize an array, lets say, int[] foo = new int[10],
then it will create a new array with 0s. Since int has 4 bytes, which is 32 bits, every time assign a value to one element, i.e., foo[4] = 5, it will do foo[32 x input(which is 4)] = value(5); That's why array is 0-indexed, and how they assign values in O(1) time.
I'm learning Java and surprisingly I found out that Java arrays are not dynamic - even though its cousing languages have dynamic arrays.
So I came out with ideas to kind of imitate a dynamic array in java on my own.
One thought I had was to copy the original array references to a temporary array, then turn the original array to null, re-set its index to a bigger value and then finally re-copy the values from the temporary array.
Example.:
if(numberOfEntries == array.length){
Type[] temp = new Type[numberOfEntries];
for(int x=0; x < numberOfEntries; x++){
temp[x] = array[x];
}
array = null;
array = new Type[numberOfEntries+1];
for(int x=0; x < numberOfEntries; x++){
array[x] = temp[x];
}
I know that this can result in data loss if the process is interrupted, but aside from that, is this a bad idea? What are my options?
Thanks!
Your idea is in the right ballpark. But for a task that you propose you should never implement your own version, unless it is for academic purposes and fun.
What you propose is roughly implemented by the ArrayList class.
This has an internal array and a size 'counter'. The internal array is filled when items are added. When the internal array is full all elements are copied to a bigger array. The internal array is never released to the user of the class (to make sure it's state is always valid).
In your example code, because an array is a pointer, you don't really need the temp array. Just create a new one, copy all elements and save the pointer to it as your array.
You might want to look into thrashing. Changing the size of the array by 1 is likely to be very inefficient. Depending on your use case, you might want to increase the array size by double, and similarly halve the array when it's only a quarter full.
ArrayList is convenient, but once it's full, it takes linear time to add an element. You can achieve something similar to resizing with the ensureCapacity() method. I'd recommend becoming more familiar with Java's Collections framework so you can make the best decisions in future by yourself.
Arrays are not dynamic their size can't change dynamically and right now you aren't changing the same object, you are replacing smaller size object with larger size object
int[5] Arr = new int[5] ; // Create an array of size 5
Arr = new int[10] ;// you assigned the different objects. It is not the same object.
So, we can't change the size of the array dynamically. You can use ArrayList for the same.
But keep try !!!
Please take a look at java.util.ArrayList which is dynamically, it is part of the Collections framework. Making the Array dynamically should be slower and error-prone.
Have you heard about time complexity , do you know how much time complexity you are increasing, Every time you are copying old array element to new array let you have 1 million element in array then think about copying time of element of one array to another array.
One more thing i want to tell you, ArrayList implementation used same logic except new length that you are using .
The method assigned in the assignment says:
boolean addLineSegment(int [] segment) - add a line segment to the database if its coordinates represent a valid line segment. This should increase the size of the lineSegment array by one and add the given line segment to the end. The method returns true if a line segment was added and false otherwise. The input should be an array of size 4.
I'm kind of stuck because I want to add a row into my array lineSegments[][] without having to reallocate it and erasing the previous contents of the array. How do I keep the contents of the array and add a new row to it so I can add the contents of segment[] to lineSegments[][]?
Use Java ArrayUtils static methods, there are many function that may help you there, like:
Add functions:
static int[] add(int[] array, int element)
Copies the given array and adds the given element at the end of the new array.
static int[] add(int[] array, int index, int element)
Inserts the specified element at the specified position in the array.
Remove functions:
static int[] remove(int[] array, int index)
Removes the element at the specified position from the specified array.
It looks like you're trying to simulate the action of an ArrayList! I'd recommend using an ArrayList to manage your list of arrays. If, however, you're only allowed to use an array, I'm afraid that unless you know how many maximum elements you're going to have in your outer array, you'll need to copy the way the ArrayList class works(with a few changes), which does indeed involve reallocating the array.
However, have no fear because you can indeed reallocate the array without losing the contents of it. In the Arrays class, there's a static method called copyOf(). This allows you to make a new array of the size you want while retaining the contents of your old array.
Let's have an example:
boolean addLineSegment(int[] segment){
if(segment is not valid)
return false;
lineSegments=Arrays.copyOf(lineSegments,lineSegments.length+1);
lineSegments[lineSegments.length-1]=segment;
return true;
}
This fulfills the requirement of increasing the size of the array by one while still retaining the old elements. For this to work, the array must start out with a size of zero, and it will then grow from then on.
This differs from the way the ArrayList class works in that while this one increases by one every time, the ArrayList class keeps track of the current index of the last element, and starts with an array of length 10, doubling every time the cap is reached. However, your requirements state that the size must increase by 1 each time so the solution I proposed should work fine.
The method assigned in the assignment says:
boolean addLineSegment(int [] segment) - add a line segment to the database if its coordinates represent a valid line segment. This should increase the size of the lineSegment array by one and add the given line segment to the end. The method returns true if a line segment was added and false otherwise. The input should be an array of size 4.
I'm kind of stuck because I want to add a row into my array lineSegments[][] without having to reallocate it and erasing the previous contents of the array. How do I keep the contents of the array and add a new row to it so I can add the contents of segment[] to lineSegments[][]?
public boolean addLineSegment(int[] segment) {
if(segment.length==4 && isValid(segment[0], segment[1], segment[2], segment[4])){
//does something that copies segment into a new row of lineSegments...
returns true;
}
return false;
}
In Java if you want to expand a primitive array you need to allocate new space and copy the entire array. There is no mechanism to expand in place (because the space after the array in memory is not part of the array).
Fortunately it's a pretty trivial thing to do in Java as Arrays.copyOf does exactly what you want it to do. You can expand the size by 1 and enter the new data.
A slightly more sophisticated way to do it is to allocate more space than initially required and keep a separate lineCount variable. Then you can expand in blocks (when lineCount == array.length) rather than each time a new line is added.
You can not do this through array unless you copy your array to a new big array.
I would suggest you use java collection instead.List>.
I am researching the difference of arrays and Arraylists. Can anyone clarify if it is possible to add an element to the middle of an array without replacing the existing value (like what the x.add() would to for an arraylist)?
For example: if I had an array of fruit [apples, pears, peaches, nectarines] and I want to insert plums [apples, pears, plums, peaches, nectarines]. Would this be possible and how would it be done?
An array size is fixed, so normally it's complicated to add an element into an array.
But in special cases it is possible:
It is only possible if the array is not yet fully filled.
Like [apples, pears, peaches, nectarines, NULL, NULL]
inserting is then possible if the current size, which you have to record on a separate place, is smaller than the array size.
Inserting then works using System.arraycopy(), where you first move all elements at inserting position and above to one position to the right. Then you add the new element.
The result would be [apples, pears, plums, peaches, nectarines, NULL]
leaving yet place for one more element.
Java's ArrayList uses this technic to provide a dynamic growing array.
In most cases it's better to use ArrayList for this task. In special cases where you have to read millions of elements such a self managed "growing" array is much more memory efficient (e.g 4 times less the memory, because ArrayList always uses Objects while array could also use primitive types, and they need less memory).
Note:
If one reads you question puristic the answer is "No", because you showed a fully filled array. The only chance to add any more element is to allocate a new array with bigger size and copy the old elements and the new one. But then you have a new array. The access to that array must be encapsulated that no one can reference it, except the class which manages the adding and getting values from it. Just look at the source code of ArrayList to get an Idea.
No, it's not possible.
You would need to allocate a new array larger than the existing one and copy everything over to it in the new positions.
No. Arrays have fixed length, and cannot be resized.
An array is a continuous region of memory - so no, you cannot add an element in the middle of an existing array. ArrayList is a List backed by an array. When necessary, ArrayList will allocate a new array and copy existing values into the newly allocate array.
392 public void add(int index, E element) {
393 rangeCheckForAdd(index);
394
395 ensureCapacity(size+1); // Increments modCount!!
396 System.arraycopy(elementData, index, elementData, index + 1,
397 size - index);
398 elementData[index] = element;
399 size++;
400 }
Read the code for ArrayList here.
const array = [1,2,3];
array.splice(2,0,5); \\ (index, number of items you want to replace, item to be replaced with separated by commas)
console.log(array); \\ [1,5,3]
array2 = [1,2,3];
array2.splice(1,0,4,5);
console.log(array2); \\ [1, 4, 5, 2, 3]
Hope this helps the JS Devs