76

I have searched for a way to resize an array in Java, but I could not find ways of resizing the array while keeping the current elements.

I found for example code like int[] newImage = new int[newWidth];, but this deletes the elements stored before.

My code would basically do this: whenever a new element is added, the array largens by 1. I think this could be done with dynamic programming, but I'm, not sure how to implement it.

Artyom Ionash
  • 405
  • 7
  • 17
Mihai Bujanca
  • 4,089
  • 10
  • 43
  • 84
  • 4
    Are you looking for [ArrayList](http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html) ? – jlordo Nov 02 '12 at 14:58

12 Answers12

121

You can't resize an array in Java. You'd need to either:

  1. Create a new array of the desired size, and copy the contents from the original array to the new array, using java.lang.System.arraycopy(...);

  2. Use the java.util.ArrayList<T> class, which does this for you when you need to make the array bigger. It nicely encapsulates what you describe in your question.

  3. Use java.util.Arrays.copyOf(...) methods which returns a bigger array, with the contents of the original array.

SamB
  • 9,039
  • 5
  • 49
  • 56
Steve McLeod
  • 51,737
  • 47
  • 128
  • 184
  • Alright, my arraylist is of a class type "checker", that stores different objects (int, string etc). I created a new object of type checker, assigned some values and added it to the arraylist. Now eclipse is going to debug mode, but not giving any error in the console. Do you know what might be the problem? – Mihai Bujanca Nov 02 '12 at 15:22
  • 4
    You should ask this as a separate question. – Steve McLeod Nov 02 '12 at 20:25
34

Not nice, but works:

    int[] a = {1, 2, 3};
    // make a one bigger
    a = Arrays.copyOf(a, a.length + 1);
    for (int i : a)
        System.out.println(i);

as stated before, go with ArrayList

jlordo
  • 37,490
  • 6
  • 58
  • 83
  • 4
    @RyanMcCullagh It's worth nothing that ArrayLists have added complexity to avoid having to make a copy of the array for every insertion or deletion. – Bernhard Barker Mar 11 '18 at 12:21
25

Here are a couple of ways to do it.


Method 1: System.arraycopy():

Copies an array from the specified source array, beginning at the specified position, to the specified position of the destination array. A subsequence of array components are copied from the source array referenced by src to the destination array referenced by dest. The number of components copied is equal to the length argument. The components at positions srcPos through srcPos+length-1 in the source array are copied into positions destPos through destPos+length-1, respectively, of the destination array.

Object[] originalArray = new Object[5];   
Object[] largerArray = new Object[10];
System.arraycopy(originalArray, 0, largerArray, 0, originalArray.length);

Method 2: Arrays.copyOf():

Copies the specified array, truncating or padding with nulls (if necessary) so the copy has the specified length. For all indices that are valid in both the original array and the copy, the two arrays will contain identical values. For any indices that are valid in the copy but not the original, the copy will contain null. Such indices will exist if and only if the specified length is greater than that of the original array. The resulting array is of exactly the same class as the original array.

Object[] originalArray = new Object[5];   
Object[] largerArray = Arrays.copyOf(originalArray, 10);

Note that this method usually uses System.arraycopy() behind the scenes.


Method 3: ArrayList:

Resizable-array implementation of the List interface. Implements all optional list operations, and permits all elements, including null. In addition to implementing the List interface, this class provides methods to manipulate the size of the array that is used internally to store the list. (This class is roughly equivalent to Vector, except that it is unsynchronized.)

ArrayList functions similarly to an array, except it automatically expands when you add more elements than it can contain. It's backed by an array, and uses Arrays.copyOf.

ArrayList<Object> list = new ArrayList<>();

// This will add the element, resizing the ArrayList if necessary.
list.add(new Object());
Double_A
  • 99
  • 1
  • 7
Anubian Noob
  • 13,426
  • 6
  • 53
  • 75
5

You could just use ArrayList which does the job for you.

Steve McLeod
  • 51,737
  • 47
  • 128
  • 184
Kirill Rakhman
  • 42,195
  • 18
  • 124
  • 148
4

It is not possible to change the Array Size. But you can copy the element of one array into another array by creating an Array of bigger size.

It is recommended to create Array of double size if Array is full and Reduce Array to halve if Array is one-half full

public class ResizingArrayStack1 {
    private String[] s;
    private int size = 0;
    private int index = 0;

    public void ResizingArrayStack1(int size) {
        this.size = size;
        s = new String[size];
    }


    public void push(String element) {
        if (index == s.length) {
            resize(2 * s.length);
        }
        s[index] = element;
        index++;
    }

    private void resize(int capacity) {
        String[] copy = new String[capacity];
        for (int i = 0; i < s.length; i++) {
            copy[i] = s[i];
            s = copy;
        }
    }

    public static void main(String[] args) {
        ResizingArrayStack1 rs = new ResizingArrayStack1();
        rs.push("a");
        rs.push("b");
        rs.push("c");
        rs.push("d");
    }
}
jrtapsell
  • 6,719
  • 1
  • 26
  • 49
2

You could use a ArrayList instead of array. So that you can add n number of elements

 List<Integer> myVar = new ArrayList<Integer>();
someone
  • 6,577
  • 7
  • 37
  • 60
2

Standard class java.util.ArrayList is resizable array, growing when new elements added.

Alexei Kaigorodov
  • 13,189
  • 1
  • 21
  • 38
1

You can't resize an array, but you can redefine it keeping old values or use a java.util.List

Here follows two solutions but catch the performance differences running the code below

Java Lists are 450 times faster but 20 times heavier in memory!

testAddByteToArray1 nanoAvg:970355051   memAvg:100000
testAddByteToList1  nanoAvg:1923106     memAvg:2026856
testAddByteToArray1 nanoAvg:919582271   memAvg:100000
testAddByteToList1  nanoAvg:1922660     memAvg:2026856
testAddByteToArray1 nanoAvg:917727475   memAvg:100000
testAddByteToList1  nanoAvg:1904896     memAvg:2026856
testAddByteToArray1 nanoAvg:918483397   memAvg:100000
testAddByteToList1  nanoAvg:1907243     memAvg:2026856
import java.util.ArrayList;
import java.util.List;

public class Test {

    public static byte[] byteArray = new byte[0];
    public static List<Byte> byteList = new ArrayList<>();
    public static List<Double> nanoAvg = new ArrayList<>();
    public static List<Double> memAvg = new ArrayList<>();

    public static void addByteToArray1() {
        // >>> SOLUTION ONE <<<
        byte[] a = new byte[byteArray.length + 1];
        System.arraycopy(byteArray, 0, a, 0, byteArray.length);
        byteArray = a;
        //byteArray = Arrays.copyOf(byteArray, byteArray.length + 1); // the same as System.arraycopy()
    }

    public static void addByteToList1() {
        // >>> SOLUTION TWO <<<
        byteList.add(new Byte((byte) 0));
    }

    public static void testAddByteToList1() throws InterruptedException {
        System.gc();
        long m1 = getMemory();
        long n1 = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            addByteToList1();
        }
        long n2 = System.nanoTime();
        System.gc();
        long m2 = getMemory();
        byteList = new ArrayList<>();
        nanoAvg.add(new Double(n2 - n1));
        memAvg.add(new Double(m2 - m1));
    }

    public static void testAddByteToArray1() throws InterruptedException {
        System.gc();
        long m1 = getMemory();
        long n1 = System.nanoTime();
        for (int i = 0; i < 100000; i++) {
            addByteToArray1();
        }
        long n2 = System.nanoTime();
        System.gc();
        long m2 = getMemory();
        byteArray = new byte[0];
        nanoAvg.add(new Double(n2 - n1));
        memAvg.add(new Double(m2 - m1));
    }

    public static void resetMem() {
        nanoAvg = new ArrayList<>();
        memAvg = new ArrayList<>();
    }

    public static Double getAvg(List<Double> dl) {
        double max = Collections.max(dl);
        double min = Collections.min(dl);
        double avg = 0;
        boolean found = false;
        for (Double aDouble : dl) {
            if (aDouble < max && aDouble > min) {
                if (avg == 0) {
                    avg = aDouble;
                } else {
                    avg = (avg + aDouble) / 2d;
                }
                found = true;
            }
        }
        if (!found) {
            return getPopularElement(dl);
        }
        return avg;
    }

    public static double getPopularElement(List<Double> a) {
        int count = 1, tempCount;
        double popular = a.get(0);
        double temp = 0;
        for (int i = 0; i < (a.size() - 1); i++) {
            temp = a.get(i);
            tempCount = 0;
            for (int j = 1; j < a.size(); j++) {
                if (temp == a.get(j))
                    tempCount++;
            }
            if (tempCount > count) {
                popular = temp;
                count = tempCount;
            }
        }
        return popular;
    }

    public static void testCompare() throws InterruptedException {
        for (int j = 0; j < 4; j++) {
            for (int i = 0; i < 20; i++) {
                testAddByteToArray1();
            }
            System.out.println("testAddByteToArray1\tnanoAvg:" + getAvg(nanoAvg).longValue() + "\tmemAvg:" + getAvg(memAvg).longValue());
            resetMem();
            for (int i = 0; i < 20; i++) {
                testAddByteToList1();
            }
            System.out.println("testAddByteToList1\tnanoAvg:" + getAvg(nanoAvg).longValue() + "\t\tmemAvg:" + getAvg(memAvg).longValue());
            resetMem();
        }
    }

    private static long getMemory() {
        Runtime runtime = Runtime.getRuntime();
        return runtime.totalMemory() - runtime.freeMemory();
    }

    public static void main(String[] args) throws InterruptedException {
        testCompare();
    }
}
Codemix
  • 56
  • 3
1

You can try below solution inside some class:

int[] a = {10, 20, 30, 40, 50, 61};

// private visibility - or change it as needed
private void resizeArray(int newLength) {
    a = Arrays.copyOf(a, a.length + newLength);
    System.out.println("New length: " + a.length);
}
Sebastian D'Agostino
  • 1,575
  • 2
  • 27
  • 44
sreenath reddy
  • 103
  • 1
  • 2
  • 9
0

It is not possible to resize an array. However, it is possible change the size of an array through copying the original array to the newly sized one and keep the current elements. The array can also be reduced in size by removing an element and resizing.

import java.util.Arrays 
public class ResizingArray {

    public static void main(String[] args) {

        String[] stringArray = new String[2] //A string array with 2 strings 
        stringArray[0] = "string1";
        stringArray[1] = "string2";

        // increase size and add string to array by copying to a temporary array
        String[] tempStringArray = Arrays.copyOf(stringArray, stringArray.length + 1);
        // Add in the new string 
        tempStringArray[2] = "string3";
        // Copy temp array to original array
        stringArray = tempStringArray;

       // decrease size by removing certain string from array (string1 for example)
       for(int i = 0; i < stringArray.length; i++) {
           if(stringArray[i] == string1) {
               stringArray[i] = stringArray[stringArray.length - 1];
               // This replaces the string to be removed with the last string in the array
               // When the array is resized by -1, The last string is removed 
               // Which is why we copied the last string to the position of the string we wanted to remove
               String[] tempStringArray2 = Arrays.copyOf(arrayString, arrayString.length - 1);
                // Set the original array to the new array
               stringArray = tempStringArray2;
           }
       }
    }    
}
Lee
  • 1
  • 1
0

Sorry, but at this time is not possible resize arrays, and may be never will be.

So my recommendation, is to think more to find a solution that allow you get from the beginning of the process, the size of the arrays that you will requiere. This often will implicate that your code need a little more time (lines) to run, but you will save a lot of memory resources.

Daniel De León
  • 13,196
  • 5
  • 87
  • 72
0

We can't do that using array datatype. Instead use a growable array which is arrayList in Java.

  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 09 '22 at 11:57