I am working on a project, but I cannot use any existing java data structures (ie, ArraysList, trees, etc)
I can only use arrays. Therefore, I need to dynamically up
you can not increase array size dynamically better you copy into new array
. Use System.arrayCopy
for that, it better than copying each element into new array. For reference
Why is System.arraycopy native in Java?.
private static Object resizeArray (Object oldArray, int newSize) {
int oldSize = java.lang.reflect.Array.getLength(oldArray);
Class elementType = oldArray.getClass().getComponentType();
Object newArray = java.lang.reflect.Array.newInstance(
elementType, newSize);
int preserveLength = Math.min(oldSize, newSize);
if (preserveLength > 0)
System.arraycopy(oldArray, 0, newArray, 0, preserveLength);
return newArray;
}
You allocate a new Array (double the capacity, for instance), and move all elements to it.
Basically you need to check if the wordCount
is about to hit the wordList.size()
, when it does, create a new array with twice the length of the previous one, and copy all elements to it (create an auxiliary method to do this), and assign wordList
to your new array.
To copy the contents over, you could use System.arraycopy
, but I'm not sure that's allowed with your restrictions, so you can simply copy the elements one by one:
public String[] createNewArray(String[] oldArray){
String[] newArray = new String[oldArray.length * 2];
for(int i = 0; i < oldArray.length; i++) {
newArray[i] = oldArray[i];
}
return newArray;
}
Proceed.
Lets take a case when you have an array of 1 element, and you want to extend the size to accommodate 1 million elements dynamically.
Case 1:
String [] wordList = new String[1];
String [] tmp = new String[wordList.length + 1];
for(int i = 0; i < wordList.length ; i++){
tmp[i] = wordList[i];
}
wordList = tmp;
Case 2 (increasing size by a addition factor):
String [] wordList = new String[1];
String [] tmp = new String[wordList.length + 10];
for(int i = 0; i < wordList.length ; i++){
tmp[i] = wordList[i];
}
wordList = tmp;
Case 3 (increasing size by a multiplication factor):
String [] wordList = new String[1];
String [] tmp = new String[wordList.length * 2];
for(int i = 0; i < wordList.length ; i++){
tmp[i] = wordList[i];
}
wordList = tmp;
When extending the size of an Array dynamically, using Array.copy or iterating over the array and copying the elements to a new array using the for loop, actually iterates over each element of the array. This is a costly operation. Array.copy would be clean and optimized, still costly. So, I'd suggest increasing the array length by a multiplication factor.
How it helps is,
In case 1, to accommodate 1 million elements you have to increase the size of array 1 million - 1 times i.e. 999,999 times.
In case 2, you have to increase the size of array 1 million / 10 - 1 times i.e. 99,999 times.
In case 3, you have to increase the size of array by log21 million - 1 time i.e. 18.9 (hypothetically).
Take a look at implementation of Java ArrayList. Java ArrayList
internally uses a fixed size array and reallocates the array once number of elements exceed current size. You can also implement on similar lines.
You have to manually create a new bigger array and copy over the items.
this may help
You can do something like this:
String [] wordList;
int wordCount = 0;
int occurrence = 1;
int arraySize = 100;
int arrayGrowth = 50;
wordList = new String[arraySize];
while ((strLine = br.readLine()) != null) {
// Store the content into an array
Scanner s = new Scanner(strLine);
while(s.hasNext()) {
if (wordList.length == wordCount) {
// expand list
wordList = Arrays.copyOf(wordList, wordList.length + arrayGrowth);
}
wordList[wordCount] = s.next();
wordCount++;
}
}
Using java.util.Arrays.copyOf(String[])
is basically doing the same thing as:
if (wordList.length == wordCount) {
String[] temp = new String[wordList.length + arrayGrowth];
System.arraycopy(wordList, 0, temp, 0, wordList.length);
wordList = temp;
}
except it is one line of code instead of three. :)