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.
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.
This question already has answers here:
Why is accessing any single element in an array done in constant time ( O(1) )?
(5 answers)
Closed 4 years ago.
One interview question which I couldn't answer and couldn't find any relevant answers online.
Suppose in an arraylist, there are 10000 data, and I want to find the number which is currently on 5000th index, how does the arraylist know the indexes and give result in constant time?
Because if we are traversing through the arraylist to find the data, it would take linear time and not constant time.
Thanks in advance.
The storage backing an ArrayList is an array. Whether primitive values or object references are stored, all objects in the array are in consecutive order in memory.
For array access, all the compiler has to do is have instructions that calculate the correct memory address based on the initial address and which index is desired, which is O(1). Then it can go directly to that calculated address. There is no traversing, so it is not O(n).
ArrayLists can be thought of as an array of Objects (Which happens to be exactly how they are implemented). You can index into it as any other array at O(1). The advantage over a true "Array" is that it tracks a "Length" independent of the array's length and automatically extends the array when it "overflows"--plus a few extra operations.
LinkedLists (probably the structure you are thinking of) require you to walk from one item to the next, so the implementation is O(n) to find an item at an index.
ArrayList
ArrayList uses an array under the hood, thus the name. Arrays are data-structures with a direct, fast, index-based access.
So if you ask for the element at index 5 000, it just asks its internal array:
// More or less
return array[5000];
Here's the full method from OpenJDK 8:
/**
* Returns the element at the specified position in this list.
*
* #param index index of the element to return
* #return the element at the specified position in this list
* #throws IndexOutOfBoundsException {#inheritDoc}
*/
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
In particular, it does not traverse all elements up to that point. That's what other data-structures, without index-based access, need to do. Such as LinkedList. Note that there is an indicator interface, called RandomAccess (documentation). Classes implementing that interface have a direct index-based access. Current implementations are:
ArrayList, AttributeList, CopyOnWriteArrayList,
RoleList, RoleUnresolvedList, Stack, Vector
How arrays work
So, how does an array have direct access to that element? Well, arrays are of fixed size. When you create it, you need to tell it the size. For example 10 000:
Foo[] array = new Foo[10000];
Your computer will then allocate contiguous memory for 10 000 objects of Foo. The key is that the memory area is contiguous, not scattered around. So the third element comes directly after the second and directly before the fourth element in your memory.
When you now want to retrieve the element at position 5 000, your computer retrieves the Foo object at the following memory position:
startAddressOfArray + 5000 * sizeOfFoo
Everything is known since declaration of the array and the computation is fast, obviously in constant time O(1). Thus, arrays have direct index-based access to their elements. Because the stuff is stored together, contiguously in memory.
You may read more about arrays on Wikipedia.
Here is an image from techcrashcourse.com showing an array with the addresses of each element:
The array is of size 7 and stores integers that use 2 bytes (16 bits). Usually called short, so a new short[7] array. You can see that each element is offset by 2 bytes (the size of a short) to its previous element. Which makes it possible to access an element at a given position directly with a simple computation, as shown.
As its name suggests, ArrayList stores elements in an array. Here is the relevant piece of code in oracle JDK :
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
*/
transient Object[] elementData; // non-private to simplify nested class access
Thus, without surprise, list.get(index) only gets the nth element in the internal array :
public E get(int index) {
Objects.checkIndex(index, size);
return elementData(index);
}
E elementData(int index) {
return (E) elementData[index];
}
So, I was reading my textbook about linked lists. So if it isn't a special case if something is inserted at the end of a linked list, is it a special case, by way of contrast if an element is inserted at the end of an array? What is the reason behind the answer. Why? Why isn't it a special case when inserted at the end of a link list and why is/isn't a special case at the end of an array? What about for ArrayLists?
It is also not a special case for Array (if we are not talking about exceeding bounds of Array). But for ArrayList it could be a special case, because ArrayList has a capacity and if it is exceded ArrayList needs to be resized in order to make sure that it has space for inserted element.
Arrays have a fixed size that you give at initialization (This part is important because array elements are stored at consecutive memory addresses). Hence, you cannot append an element to an array without creating a new array.
int[] myArray = new int[10];
myArray.append(42); //Where should it be stored? It would not make sense.
For lists, it depends on the list implementation. The LinkedList consists of several Node connected to each other. Hence, adding an element to the end of the list is equivalent to connecting a new Node to the last Node of the list.
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