How can we dynamically allocate and grow an array

前端 未结 8 1779
伪装坚强ぢ
伪装坚强ぢ 2020-12-05 16:01

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

相关标签:
8条回答
  • 2020-12-05 16:41

    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;
    }
    
    0 讨论(0)
  • 2020-12-05 16:44

    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.

    0 讨论(0)
  • 2020-12-05 16:51

    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).

    0 讨论(0)
  • 2020-12-05 16:55

    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.

    0 讨论(0)
  • 2020-12-05 16:57

    You have to manually create a new bigger array and copy over the items.

    this may help

    0 讨论(0)
  • 2020-12-05 17:01

    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. :)

    0 讨论(0)
提交回复
热议问题