Het formaat van een array wijzigen terwijl de huidige elementen in Java blijven?

Ik heb gezocht naar een manier om de grootte van een array in Java te wijzigen, maar ik kon geen manieren vinden om de grootte van de array te wijzigen met behoud van de huidige elementen.

Ik heb bijvoorbeeld code gevonden zoals int[] newImage = new int[newWidth];, maar hiermee worden de eerder opgeslagen elementen verwijderd.

Mijn code zou in principe dit doen: telkens wanneer een nieuw element wordt toegevoegd, wordt de array 1groter. Ik denk dat dit kan worden gedaan met dynamisch programmeren, maar ik weet niet zeker hoe ik het moet implementeren.


Antwoord 1, autoriteit 100%

Je kunt de grootte van een array niet wijzigen in Java. U moet ofwel:

  1. Maak een nieuwe array van de gewenste grootte en kopieer de inhoud van de originele array naar de nieuwe array met java.lang.System.arraycopy(...);

  2. Gebruik de java.util.ArrayList<T>, die dit voor u doet wanneer u de array groter moet maken. Het vat mooi samen wat je in je vraag beschrijft.

  3. Gebruik java.util.Arrays.copyOf(...)methoden die een grotere array retourneert, met de inhoud van de originele array.


Antwoord 2, autoriteit 27%

Niet leuk, maar werkt:

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

zoals eerder vermeld, ga met ArrayList


Antwoord 3, autoriteit 21%

Hier zijn een aantal manieren om dit te doen.


Methode 1: System.arraycopy():

Kopieert een array van de opgegeven bronarray, beginnend op de opgegeven positie, naar de opgegeven positie van de doelarray. Een subreeks van arraycomponenten wordt gekopieerd van de bronarray waarnaar wordt verwezen door src naar de doelarray waarnaar wordt verwezen door dest. Het aantal gekopieerde componenten is gelijk aan het lengteargument. De componenten op posities srcPos tot en met srcPos+length-1 in de bronarray worden respectievelijk gekopieerd naar de posities destPos tot en met destPos+length-1 van de doelarray.

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

Methode 2: Arrays.copyOf():

Kopieert de opgegeven array, het afknippen of opvullen met nullen (indien nodig), zodat de kopie de opgegeven lengte heeft. Voor alle indices die geldig zijn in zowel de oorspronkelijke array als de kopie, bevatten de twee arrays identieke waarden. Voor eventuele indices die geldig zijn in de kopie, maar niet het origineel, bevat de kopie null. Dergelijke indices zullen bestaan ​​als en alleen als de opgegeven lengte groter is dan die van de originele array. De resulterende array is van precies dezelfde klasse als de originele array.

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

Merk op dat deze methode meestal gebruikt System.arraycopy()Achter de scènes .


Methode 3: ArrayList:

Revisable-array implementatie van de lijstinterface. Implementeert alle optionele lijstactiviteiten en maakt alle elementen, waaronder NULL mogelijk. Naast het implementeren van de lijstinterface, biedt deze klasse methoden om de grootte van de array die intern wordt gebruikt om de lijst te bewaren te manipuleren. (Deze klasse is ongeveer gelijk aan vector, behalve dat het niet gesynchroniseerd is.)

ArrayList werkt op dezelfde manier als een array, behalve dat het automatisch wordt uitgevouwen wanneer u meer elementen toevoegt dan het kan bevatten. Het is ondersteund door een arrayen gebruikt Arrays.copyOf.

ArrayList<Object> list = new ArrayList<>();
// This will add the element, resizing the ArrayList if necessary.
list.add(new Object());

Antwoord 4, autoriteit 5%

U kunt gewoon ArrayListgebruiken, die het werk voor u doet.


Antwoord 5, autoriteit 3%

Het is niet mogelijk om de arraygrootte te wijzigen.
Maar u kunt het element van de ene array naar een andere array kopiëren door een array van groter formaat te maken.

Het wordt aanbevolen om een array van dubbele grootte te maken als de array vol is en de array te halveren als de array halfvol is

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

Antwoord 6, autoriteit 2%

Je zou een ArrayList kunnen gebruiken in plaats van een array. Zodat u n aantal elementen kunt toevoegen

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

Antwoord 7, autoriteit 2%

Standaardklasse java.util.ArrayList is een array waarvan de grootte kan worden gewijzigd, en groeit als er nieuwe elementen worden toegevoegd.


Antwoord 8

U kunt de grootte van een array niet wijzigen, maar u kunt deze opnieuw definiëren met behoud van oude waarden of een java.util.List gebruiken

Hier volgen twee oplossingen, maar vang de prestatieverschillen met de onderstaande code

Java-lijsten zijn 450 keer sneller, maar 20 keer zwaarder in geheugen!

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

Antwoord 9

Je kunt onderstaande oplossing in een klas proberen:

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

Antwoord 10

Het is niet mogelijk om het formaat van een array te wijzigen. Het is echter mogelijk om de grootte van een array te wijzigen door de originele array naar de nieuw formaat te kopiëren en de huidige elementen te behouden. De array kan ook in omvang worden verminderd door een element en het formaat te verwijderen.

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

Antwoord 11

Sorry, maar op dit moment is het niet mogelijk om de grootte van arrays te wijzigen, en dat zal misschien ook nooit gebeuren.

Dus mijn aanbeveling is om meer na te denkenom een oplossing te vinden waarmee je vanaf het begin van het proces de grootte van de arrays kunt krijgen die je nodig hebt. Dit houdt vaak in dat uw code iets meer tijd (regels) nodig heeft om te worden uitgevoerd, maar u bespaart veel geheugenbronnen.

Other episodes