Resize an Array while keeping current elements in Java?

JavaArrays

Java Problem Overview


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.

Java Solutions


Solution 1 - Java

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.

Solution 2 - Java

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

Solution 3 - Java

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());

Solution 4 - Java

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

Solution 5 - Java

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");
    }
}

Solution 6 - Java

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

 List<Integer> myVar = new ArrayList<Integer>();

Solution 7 - Java

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

Solution 8 - Java

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();
    }
}

Solution 9 - Java

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);
}

Solution 10 - Java

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;
           }
       }
    }    
}

Solution 11 - Java

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.

Solution 12 - Java

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMihai BujancaView Question on Stackoverflow
Solution 1 - JavaSteve McLeodView Answer on Stackoverflow
Solution 2 - JavajlordoView Answer on Stackoverflow
Solution 3 - JavaAnubian NoobView Answer on Stackoverflow
Solution 4 - JavaKirill RakhmanView Answer on Stackoverflow
Solution 5 - JavaRanjeet KumarView Answer on Stackoverflow
Solution 6 - JavasomeoneView Answer on Stackoverflow
Solution 7 - JavaAlexei KaigorodovView Answer on Stackoverflow
Solution 8 - JavaCodemixView Answer on Stackoverflow
Solution 9 - Javasreenath reddyView Answer on Stackoverflow
Solution 10 - JavaLee View Answer on Stackoverflow
Solution 11 - JavaDaniel De LeónView Answer on Stackoverflow
Solution 12 - JavaPraveen BabuView Answer on Stackoverflow