So I just discovered that Java allows us to create arrays of size 0. Does that mean that the array is both empty and full at the same time? I figured this out while working on an array based implementation of a priority queue. Would it be right to say that it is empty and full at the same time when calling methods checking for this? Or should I not allow the creation of an array of size 0? Thanks.
Java arrays have no definition of full or of empty. Consider
int[] foo = {0};
int[] bar = new int[1];
Is foo full because it has a value assigned to its only position?
Is bar empty because it has no values assigned?
Both arrays are the same, they both have one value stored and in both cases the contain the value 0.
Full implies you can't add any more items, you can never add new items to java arrays, just replace existing items, so either all arrays are full or full does not make sense for a java array. I say it is the second.
Related
I was writing something that needs an arrayList of size n, so I did the following:
List<Set<Integer>> list = new ArrayList<Set<Integer>(n);
And when I was trying to access an element of the list e.g.
list.get(someValue that is <n)
I got arrayList out of bound exception, so I guess putting a n there doesn't really help you initialize the list, but just pre-allocate the space.
Is there a way to do the initialization after which there are actually null or objects in each slot?
I end up using a for loop and adding n empty set and then index into the list.
Is there a better way TO INITIALIZE AN ARRAYLIST IF THE SIZE IS KNOWN IN ADVANCE?
Please know what I'm asking before saying this is a duplicate.
Hope my question is clear.
Thanks in advance.
Some of you think what I tried to do is meaningless. This happens when I tried to solve a bucket sort related problem where the index of the set I tried to access in the array is known. So for example, I want to add some elements to the set at position 1, 3, 2, 4... then it would be convenient if I can just get the set at position 1, 3, 2, 4...
If you take a look at Java API documentation, you will see that there are 3 constructors provided for ArrayList:
ArrayList()
ArrayList(Collection c) - Constructs a list containing the elements of the specified collection, in the order they are returned by the collection's iterator.
ArrayList(int initialCapacity) - Constructs an empty list with the specified initial capacity.
You can use second of listed constructors if you need to fill ArrayList's slots in the place of its definition. You need to be aware that there needs to be passed a Collection, so you can do something like that, for example:
ArrayList<Integer> al = new ArrayList<>(Arrays.asList(1,2,3,4,5);
Now size() of al is 5 and it is filled with numbers 1,2,3,4 and 5.
Also, you need to be aware that ArrayList doesn't work like Arrays and it's size is not fixed - it changes due to adding or removing items.
I'm taking the liberty of repeating bcsb1001's solution, which is perhaps obscured by various comments. In order to initialize an array of a fixed size with valid placeholder values:
new ArrayList (Collections.nCopies (n, null));
This idea was the best I could find in various searches, maybe it will work for others too.
I have a function called resolveClash, which I send an array
(in this case - combinsFinal) with 2 or more objects in it of type ModuleLecturerStudentCombination (this is my own class). Essentially what the resolveClash function does is it puts the array into an arraylist, removes the first element/object in the array and then returns the list. However, when I inspect the state of the returned value in debug mode (eclipse), it shows that a null value has been added onto the end of the arraylist.
I have looked up "removing objects correctly" etc, however, everything I have tried so far doesn't get rid of the null. The null appears after I perform the remove. I have thoroughly checked that there is not a null being passed in etc. This is a problem because when I use this and iterate through it later, it picks up a null and gives me a nullpointerexception error. Could someone please let me know what I am doing wrong or point me in the right direction?
Thanks in advance!
picture displaying problem
resolveClash(combinsFinal);
public ArrayList <ModuleLecturerStudentCombination> resolveClash(ModuleLecturerStudentCombination[] combinationArr){
ArrayList<ModuleLecturerStudentCombination> copyCombinationList = new ArrayList<ModuleLecturerStudentCombination>(Arrays.asList(combinationArr));
copyCombinationList.remove(0);
return copyCombinationList;
}
...when I inspect the state of the returned value in debug mode, it shows that a null value has been added onto the end of the arraylist
This is the normal way it works. The data within the ArrayList is stored in an array, which then is wrapped in the class to behave in the way a list does. If you add elements and the array is to small it will create a bigger one and copy the objects.
However if you remove some, it wont create a new shorter array, but simply leave some free spots at the end, but only give you access to the first ones that should be their. In the Debug mode you should also see a variable called size which tells you which part of the array is still part of the list.
In your case the ArrayList method toArray(T []) is not returning a new array. From the documentation:
[...] If the list fits in the specified array, it is returned therein.
Otherwise, a new array is allocated with the runtime type of the
specified array and the size of this list.
If the list fits in the
specified array with room to spare (i.e., the array has more elements
than the list), the element in the array immediately following the end
of the collection is set to null. [...]
The array combinsFinal has greater size than the list so the result is returned directly into it with an additional null. In this case no new array with the correct size is created.
To avoid this, since you cannot change the size of an array, you could create a new one with the same size of the list, then this would work correctly:
combinsFinal = new ModuleLecturerStudentCombination[temp.size()];
temp.toArray(combinsFinal);
or alternatively just pass an array with no size so the method will be forced to create and return a new array with the correct size:
combinsFinal = temp.toArray(new ModuleLecturerStudentCombination[0]);
As far as I know, we can pass multiple dimensional array to a method in Java without size info, like this:
void foo(int arr[][][])
But in C++, you can only exclude the size of the outer-most dimension, like this:
void foo(int arr[][y_size][z_size)
Now I understand that in C++, 'arr' will decay to a pointer, so the compiler needs to know how much elements to skip between two pointers.
My question is, what happens underneath Java makes it smarter than C++ on this, so it can distinguish the bounds between elements without knowing the size of each dimension?
C is passing an address to one contiguous area of memory. The recipient needs all but one of the dimensions in order to compute the locations of array elements in memory.
Java is passing a reference to an array object that knows its contents and size. A multidimensional array is not one contiguous area of memory. The computation made by C does not occur. Instead, the multidimensional array is comprised of multiple 1D arrays. Each level but the last is an array of references to arrays.
Array length is still used by Java during array access. Every array access is checked at runtime. If the requested index is greater than or equal to the length (or less than zero), an ArrayIndexOutOfBoundsException is thrown.
Two things:
Every array, which is a run-time object, in Java has a length property associated with it.
In C, excluding C99 VLAs, arrays are only a compile-time type describing how to access objects therein per a particular layout.
Multi-dimensional arrays in Java are always jagged arrays.
This means that the length per/in the type is not even particularly relevant in Java - every "multi-dimensional array" access goes one array at a time so
r = a[x][y][z]
is merely
a_ = a[x]
b_ = a_[y]
r = b_[z]
and there is is no dimension-to-linear calculation involved.
In java arrays are objects which effectively consist of a pointer, and the size of the array.
So in java the extra information is included in the array object.
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 wanted to know if the Java arrays are fixed after declaration. When we do:
int a[10];
and then can we do:
a = new int [100];
I am unsure if the first statement already allocates some memory and the second statement allocates a new chunk of memory and reassigns and overwrites the previous reference.
Yes it is:
The length of an array is established when the array is created. After
creation, its length is fixed.
Taken from here.
Also, in your question the first scenario: int a[10] is syntactically incorrect.
The second statement allocates a new chunk of memory, and the previous reference will eventually be garbage collected.
You can see it by yourself using a java debugger. You will notice that a will point to a different location after the second statement executes.
Good luck with your H.W.
Array have fixed length that is determined when you create it. If you want a data structure with variable length take a look at ArrayList or at LinkedList classes.
Array has fixed length but if you want the array size to be increased after this:
private Object[] myStore=new Object[10];
In normal way you have to create another array with other size and insert again all element by looping through the first array,but arrays class provide inbuild method which might be useful
myStore = Arrays.copyOf(myStore, myStore.length*2);