Consider a nested array in java. Does the top level of the array contain references to the inner arrays, or does the memory actually contain the inner arrays themselves?
If you need an illustration, assume I have access to a reverse method, which will reverse an array in place by doing multiple swaps. If I call reverse on the top-level of an M*N nested array, what will that method simply swap references around (an O(m) operation), or will it be swapping entire rows around (an O(m*n) operation)?
In a word references. Arrays themselves are likely to be contiguous blocks, but it's unlikely that the Objects the elements refer to are.
This article sums it up nicely http://java.dzone.com/articles/what-does-java-array-look
I believe you can find the answer in most introductory Java book (although it may be not that obvious).
In Java, nested/multi-dimension array is not a continuous block. It is simply an array of "reference to array".
Related
I was reading about data locality and want to use it to improve my game engine that I'm writing.
Let's say that I have created five objects at different times that are now all in different places in the memory not next to each other. If I add them all to an array, will that array only hold pointers to those objects and they will stay in the same place in the memory or will adding them all to an array rearrange them and make them contiguous.
I ask this because I thought that using arrays would be a good way to make them contiguous, but I don't know if an array will fix my problem!
tl;dr
Manipulating an array of references to objects has no effect on the objects, and has no effect on the objects’ location in memory.
Objects
An array of objects is really an array of references (pointers) to objects. A pointer is an address to another location in memory.
We speak of the array as holding objects, but that is not technically accurate. Because Java does not expose pointers themselves to us as programmers, we are generally unaware of their presence. When we access an element in the array, we are actually retrieving a pointer, but Java immediately follows that pointer to locate the object elsewhere in memory.
This automatic look-up, following the pointer to the object, makes the array of pointers feel like an array of objects. The Java programmer thinks of her array as holding her objects when in reality the objects are a hop-skip-and-a-jump away.
Arrays in Java are implemented as contiguous blocks of memory. For an array of objects, the pointers to those objects are being stored in contiguous memory. But when we access the elements, we are jumping to another location in memory to access the actual object that we want.
Adding elements may be “cheap” in that if memory happens to be available next door in memory, it can be allocated to the array to make room for more elements. In practice this is unlikely. Chances are a new array must be built elsewhere in memory, with all the pointers being copied over to the new array and then discarding the original array.
Such a new-array-and-copy-over is “expensive”. When feasible, we want to avoid this operation. If you know the likely maximum size of your array, specify that size when declaring the array. The entire block of contiguous memory is claimed immediately, with empty content in the array until you later assign a pointer to the elements.
Inserting into the middle of an array is also expensive. Either a new array is built and elements copied over, or all the elements after the insertion point must be moved down into their neighboring position.
None of these operations to the array affect the objects. The objects are floating around in the ether of memory. The objects know nothing of the array. Operations on the array do not affect the objects nor their position in memory. The only relationship is that if the reference held in the array is the last reference still pointing to the object, then when that array element is cleared or deleted, the object becomes a candidate for garbage-collection.
Primitives
In Java, the eight primitive types (byte, short, int, long, float, double, boolean, and char) are not objects/classes and are not Object-Oriented Programming. One advantage is that they are fast and take little memory, compared to objects.
An array of primitives hold the values within the array itself. So these values are stored next to one another, contiguous in memory. No references/pointers. No jumping around in memory.
As for adding or inserting, the same behavior discussed above applies. Except that instead of pointers being shuffled around, the actual primitive values are being shuffled around.
Tips
In business apps, it is generally best to use objects.
That means using the wrapper classes instead of primitives. For example, Integer instead of int. The auto-boxing facility in Java makes this easier by automatically converting between primitive values and their object wrapper.
And preferring objects means using a Collection instead of arrays, usually a List, specifically a ArrayList. Or for immutable use, a List implementation returned from the new List.of method.
In contrast to business apps, in extreme situations where speed and memory usage are paramount, such as your game engine, then make the most of arrays and primitives.
In the future, the distinction between objects and primitives may blur if the work done in Project Valhalla comes to fruition.
The data or the values are stored in the objects and the values are retrieved using the references of the objects. lemme clear one more thing arrays in Java are stored in the form of objects. so there is no doubt that objects stores values and accessed using reference variable of that particular object. Hope you got it.
Java deals with references to objects only. As such, there's no guarantee that the elements of an array will be contiguous in memory.
Edit: Guess this answer wasn't that clear. My bad. I meant that there's no guarantee that the objects themselves will be contiguous, in spite of the fact that the references will be, as 1-D arrays are stored contiguously. Still, Basil Bourque's answer perfectly explains how this works.
I recently appeared for an interview in which the interviewer asked me a question regarding Arrays and ArrayList.
He asked me if an array of arrays can be multidimensional, then why is an ArrayList of ArrayList's not multidimensional?
For example:
// Multidimensional
int[][] array = new int[m][n];
// Not multidimensional
ArrayList<ArrayList<Integer>> seq = new ArrayList<ArrayList<Integer>>();
Can anyone help me to understand this?
Cay S. Horstmann has stated within his book Core Java for the impatient:
There are no two-dimensional array lists in Java, but you can declare a
variable of type ArrayList<ArrayList<Integer>> and build up the rows
yourself.
due to the fact that ArrayLists can expand and shrink and become jagged rather than multi-dimensional, one could say it is not a two-dimensional array, multi-dimensional meaning fixed rows and columns, hence why I have also stated within the comments Java doesn't have true multi-dimensional arrays but this is outside the scope of your question.
if you're curious as to why I said Java doesn't have true multi-dimensional arrays have a read at the differences between a multidimensional array and an array of arrays in C#?
Just to make my answer clearer regarding whether Java has true multi-dimensional arrays or not, I did not say java doesn't have multi-dimensional arrays, I said Java doesn't have true multi-dimensional arrays and as expect the JLS has stated:
A multidimensional array need not have arrays of the same length at
each level.
For the same reason the shopping bag I put all my spare shopping bags into is not a multidimensional shopping bag.
If I put a nut in one bag then put that bag in another bag, I have to perform two operations to get the nut.
If I instead put the nut in a two dimensional component tray, I can perform one operation to access it using two indices:
source
Similarly, there is a fundamental difference between a list of lists ( or array of arrays ) and a true two dimensional array - a single operation taking two indices is used to access the elements in a two dimensional array, two operations each taking one index are used to access the elements in a list of lists.
An ArrayList has a single index, so it has a rank of 1. A two dimensional array has two indices, its rank is 2.
note: by 'two dimensional array' I am not referring to a Java array of (references to) arrays, but a two dimensional array as found in other languages such as FORTRAN. Java does not have multidimensional arrays. If your interviewer was specifically referring to Java 'arrays of arrays' then I would disagree with them, as Java's int[][] defines an array of references to arrays of integers, and that requires two dereferencing operations to access the elements. An array of arrays in C for example supports access with a single dereferencing operation so is closer to the multidimensional case.
I'm going to go out on a limb here and answer this one, however there is no correct answer for this broad question.
We first have to ask, what makes an array multidimensional?
I'm going to assume that your interviewer considers a multidimensional array one with a fixed size (as you've shown in your question), where it cannot be considered "jagged". According to Microsoft, a jagged array in C# is as follows:
The elements of a jagged array can be of different dimensions and sizes.
In Java, a multidimensional array is simply an array, where each element is also an array. These arrays must be defined with a fixed size in order for elements to be indexed within them, but jagged arrays can be of different sizes, as stated above.
An ArrayList is backed by an array; however, the array expands when a certain number of elements are added to it. For this reason, the ArrayList could become jagged, and could be considered not to be multidimensional any longer.
Edit: After rereading everything over a few times, I'm sure that your interviewer was just trying to confuse you. It honestly doesn't make sense for one data type (an array) to be multidimensional, and another data type (an ArrayList that uses an array) to not be multidimensional.
Looking at it from the other side: you can use lists in the very same way as "multi dimensional" arrays. You only have to replace array[row][column] with someList.get(row).get(column)!
And in the end, java arrays are implemented in similar ways: a two dim matrix is also just a one dim array of one dim arrays! In other words: the difference is more on the surface, not rooted in deep conceptual reasons!
And to be really precise: the Java type system allows you to put down Object[][] so in that sense, it knows that type of Object[][]; but as said, in reality, there are no multi-dimensional arrays; as Java sees that "two dim" thing as an array of references to arrays!
On the other hand: there is a certain notion of "multi dimensional arrays", as for example the JVM specification explicitly mentions:
The first operand of the multianewarray instruction is the run-time constant pool index to the array class type to be created. The second is the number of dimensions of that array type to actually create. The multianewarray instruction can be used to create all the dimensions of the type, as the code for create3DArray shows. Note that the multidimensional array is just an object and so is loaded and returned by an aload_1 and areturn instruction, respectively.
The interviewer's claim is nonsensical.
One can argue, as you see on this page, that Java does not have true multidimensional arrays, in which case it does not have multidimensional ArrayLists either. On the other hand, it certainly allows you to represent multidimensional structures via arrays and ArrayLists in the same way.
To define a major distinction between the two is fairly arbitrary and pointless.
Possibly the interviewer was just trying to start a technical debate, to test your ability to explain the details.
An ArrayList is an implementation of List. It's a List that is implemented using arrays. The usage of arrays is an implementation detail. The list interface doesn't support the concept of multi-dimensional lists therefore you wouldn't expect ArrayList to either. Further it isn't addressed as a use case of a traditional list data structure.
Arrays support multi-dimensionality because it's a language feature of Java.
Because it isn't dimensional at all. It is an object with an API. Any appearance of multi-dimensionality is provided by its API, but it is purely in the eye of the beholder. An array on the other hand is dimensional, and can therefore be multidimensional too.
What determines whether one should be used over the other?
I used to think that the deciding factor is whether you know the size of the things you want to store but I think there might be more to it than that.
Some more differences:
First and Major difference between Array and ArrayList in Java is that Array is a fixed length data structure while ArrayList is a variable length Collection class. You can not change length of Array once created in Java but ArrayList re-size itself when gets full depending upon capacity and load factor. Since ArrayList is internally backed by Array in Java, any resize operation in ArrayList will slow down performance as it involves creating new Array and copying content from old array to new array.
Another difference between Array and ArrayList in Java is that you can not use Generics along with Array, as Array instance knows about what kind of type it can hold and throws ArrayStoreException, if you try to store type which is not convertible into type of Array. ArrayList allows you to use Generics to ensure type-safety.
One more major difference between ArrayList and Array is that, you can not store primitives in ArrayList, it can only contain Objects. While Array can contain both primitives and Objects in Java. Though Autoboxing of Java 5 may give you an impression of storing primitives in ArrayList, it actually automatically converts primitives to Object.
Java provides add() method to insert element into ArrayList and you can simply use assignment operator to store element into Array e.g. In order to store Object to specified position.
One more difference on Array vs ArrayList is that you can create instance of ArrayList without specifying size, Java will create Array List with default size but its mandatory to provide size of Array while creating either directly or indirectly by initializing Array while creating it. By the way you can also initialize ArrayList while creating it.
Use array when you know the exact size of the collection and you don't expect to add/remove elements.
Use List (ArrayList) when you don't know the exact size of the collection and you expect to alter it at some point.
If you're using Java8, there is the Stream API, which helps to significantly reduce the boilerplate code when working with collections. This is another plus for ArrayList (and all Collections and Maps).
More info:
Arrays vs ArrayList in performance
Unless speed is critical (really critical, like every microsecond counts), use ArrayList whenever possible. It's so much easier to use, and that's usually the most important thing to consider.
Generally, I use ArrayList, not arrays, because they offer a lot of several methods that are very usefull. I think you can use array if performance is very important, in very special cases.
Array is fixed, ArrayList is growable.If the number of elements is fixed, use an array
Also one of the great benefits of collection implementations is they give you a lot of flexibility. So depending on your need, you can have a List behave as an ArrayList or as a LinkedList and so on. Also if you look at the Collection API, you'd see you have methods for almost everything you'd ever need to do.
in java, if we store 4 elements in array and array list, is it same at low level in memory OR does it make any difference in order to store elements ?
It's going to be different. An ArrayList is a wrapper around the array with several other helper functions. The memory footprint is going to be a little bit bigger for ArrayList, and it will resize itself as necessary.
It differs, ArrayList internally manages its own array for storage and has own attributes also
An array is pretty different from a List, even if the list happens to be an ArrayList and internally uses just an array as well.
For the array there exists just the array (for this discussion I'll ignore the memory the elements will occupy). Thus you have one object in the heap, the array itself.
For the ArrayList, there exists the ArrayList instance and that instance internally has an array. So there are two objects on the heap. Also, while you have exact control over the size of an array you create, the array held by the ArrayList can have any size that is >= number of elements <= Integer.MAX_VALUE.
Coincidentily, ArrayList uses an elements index directly as array index internally, so the order of elements is the same as in a plain array. But thats an implementation detail, and you normally don't care how a List organizes its data internally (after all the purpose of Lists is to abstract the messy details away).
I've been thinking about this one for a long time. What is the difference between Vectors and Arrays? I know they do similar things, if not exact.
String Array
String[] array = new String[4];
String Vector
Vector<String> vector = new Vector<String>(4);
It seems kind of redundant to me why there would be both arrays and vectors. Are there any advantages or disadvantages to using one or the other?
Vectors are resizable. Arrays are not.
The difference is that 'Vector' is an extension by programmers, whereas an array is a built-in function of the language itself.
You can edit how the Vector behaves (by editing its source code), whereas an array is defined by the compiler.
And obviously, Vectors can be potentially sized (depending on implementation). Arrays are static and cannot be resized - you have to recreate it and copy the data over.
Vector is synchronized. Arrays are not(?).
Array cannot be re-sized, while Vectors can.
Vector uses Arrays internally. The main advantage of a Vector compared to an Array is its automatical increase of capacity. An Array keeps its size once created, a Vector does not
It seems kind of redundant to me why there would be both arrays and
vectors
For one, Vectors can be resized. If you declare an array of size 10, you are left with 10 always, unless you copy the contents to another larger sized array. Methods of Vector are synchronized.
Vectors are part of the collections framework. Vector is a List. There are other lists, ArrayLists, LinkedLists etc with specific features. There are Sets and Maps. All of them hold "lists" of items, but each of them give specific advantages in specific situations.
You might want to read about java collections.
Vectors will automatically resize for you to accommodate as many entries as you want in them. An array is fixed in size, and will give you an OutOfBounds exception when you try to add more than you allocated.
When you provide the size for a vector, that's just the original size it starts with. It'll automatically grow/shrink as necessary.
1- Vectors are resize-able, arrays are not
2- Vectors are responsible for memory allocate and release, arrays are not. This makes vectors safer to use than arrays.
3- Vectors have a good performance on their implemented functions, which you may not reach by your own programming with arrays.
4- Finally I think it's wiser to use vectors, most of the times.
An array is a basic java data structure, whose size is fixed when defined.
A Vector is part of the Java Collections Framework, and contrary to your beliefs, or not even close to the same thing as an array. Among many other things, Vectors are resizable and can interact with other collections.
Java array types are not necessary. They actually create a lot of problems. Avoid them if you can.
We could do better to replace them with a standard class Array<T>. Some new post-Java languages are taking this approach.
(History alert) In the old days, Java didn't have generics, a non-generic collection class would suck to use (with lots of castings). Then array types were really poor man's generics because they carry element type info. That's why many methods return arrays, instead of List.
I think the above suggestion is not good. Check this link to get brief idea.
Difference b/w Array and Vector
Vectors help to insert and delete elements easily while arrays helps to sort and access elements with ease.
Vectors can hold different type of elements
Arrays only the type defined when forming them
You can use array list which is some what similar to vector and provided much better features