I am learning about array as a data structure and I'm interested in how exactly in Java we obtain an element in an array by index.
What's happening under the hood when the following code is executed:
...
int i = array[2];
How JVM stores refferences to primitive types in array? How we obtain the element in O(1)? Does JVM calculates position of the element relative other element?
Arrays like int[], double[], etc. Is native arrays.
The Reference to native array is the reference to its first element.
Element with index "i" will be getted by dereferencing ("reference on the first element" + i * sizeOf("contained type")).
P.s. In the Java they are wrapped in other class for checking bounds, getting length and so on. In the low-level programming languages like C++ you can broke your programm, when u will try to change element by index grater than array length
Related
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];
}
Im checkin a code in c++ and i'm trying to "translate" it to java. i wonder what this line does... (both are int arrays)
frequencies[values[i]]++;
and how can i translate it?
This is the code I extrated the line from
https://github.com/Tomaszal/HackerEarth/blob/master/Data%20Structures/Stacks/Fight%20for%20Laddus/main.c
I believe it gets the value from the i-th element in the values array, searches for it in the frequencies array and add 1+ to the index...I don't really get it
This was my attempt to the code above
int y=values[p];
frequencies[y]=frequencies[y]+1;
It gets the value from i-th element in the values array and passes this value as an indexer to frequencies array and increments the returned value by 1. A perfect translation would be
Increment the (i-th value)th value of frequencies by 1.
and it surely works the same in Java. You don't need to convert it to any other statement(s) in Java to work.
I just looked up array and arrayList
and found out that an array is fixed length and can't be changed while an arraylist can be changed and is variable in length
my question is:
is array == tuple in python?
and is arraylist == list in python?
and if they aren't what are array and arraylist's python equivalent?
ArrayList in java and list in python are both dynamic arrays. They both have O(1) average indexing time and O(1) average adding an element to the end time.
Array in java is not tuple in python. While it is true that you cannot add elements to both data structures. Python tuple does not support assignment, that is you cannot reassign individual elements in a tuple, while you can in java Array.
Java's ArrayList is similar to Python's List.
Nicer than Array for adding and removing items.
Java's Array has fixed length like you
mentioned.
Not sure what its equivalent in Python would be.
I was just playing around with JavaScript and got stuck with a simple program.
I declared an array in JavaScript like
var a = [0, 1, 2];
Then as there is no fixed size for an array in JavaScript and we can add more to the array, I added another integer to array.
a[3] = 3;
And as expected If I try to access a[4] I am definitely going to get it as undefined.
Now, if I take an array
var a = [0,1,2];
And add another element
a[4] = 4;
I have intentionally not defined a[3], and this also gives me a[3] as undefined.
Here is a fiddle where this can be observed: http://jsfiddle.net/ZUrvM/
Now, if I try the same thing in Java,
int[] a = new int[4];
a[0] = 0;
a[1] = 1;
a[3] = 3;
Then I end up with
a[2] = 0;
You can see this on ideone: https://ideone.com/WKn6Rf
The reason for this in Java I found is that the four variables are defined while declaring the array and we can only assign values to the declared size of array.
But in JavaScript when I declare an array of size 3 and then add 5th element why does it not consider the 4th element to be null or 0 if we have increased the array size beyond 4?
Why do I see this strange behavior in JavaScript, but not in other languages?
Why is this strange behavior in JavaScript?
Because arrays are only objects. If you access a nonexisting property, you get back undefined. You simply didn't assign an element at index 3, so there is nothing.
Auto-growing the array by assigning higher indices does not change this behaviour. It will affect the .length property, yes, but the intermediate indices will stay nonexistent. This is known as a sparse array.
Why is this strange behaviour in Java / C / C++?
Because arrays are chunks of allocated memory, and when allocating an array of size 4, all its elements take their values from that memory location. To avoid indeterminate values, in some languages/occasions the fields get default-initialised, typically with 0.
JavaScript isn't a strongly typed language.
In Java you declared an array of integers. The default value of any element in that array is 0.
In JavaScript, when you declare an array, the default value is undefined as it can hold anything, number, string, any object (including another array). All elements of a JavaScript array don't have to be the same type.
An array is a continuous collection of data. Say if you have a value at index 1 and index 10, the rest will be filled by undefined.
You can't create an array with empty values. 'Empty in your sense', is not undefined or null, it's empty :)
That continuous data is undefined means default assignment in JavaScript.
Say if you defined a variable,
var X;
console.log(X) //Undefined
it's not null. null is a user explicitly specifying a way to tell there is an empty data, and undefined is the JavaScript engine way.
I am just beginning to learn Java and heard that getting the size of an array is O(1). Why is it not O(n)?
Mustn't the java virtual machine count the number of items in the array?
No, the number of items in the array is fixed when you create it.
Mustn't the java virtual machine count the number of items in the array?
That is not necessary. The JVM representation for an array has a special field that gives the length of the array instance, and a special bytecode for accessing it. When it needs the length, the JVM uses these.
(It is also true that an array's length is fixed when the array has been created ... but that doesn't directly answer the question. Hypothetically, the JVM could still count elements. However, I find it hard to see how the JVM would decide where / when to stop counting elements. How would it know when the bits it is looking at don't represent a valid value of the array base-type?)
As mentioned above, it's a special bytecode function:
http://en.wikipedia.org/wiki/Java_bytecode_instruction_listings
arraylength be arrayref → length get the length of an array