在Java中保留当前元素的同时调整数组的大小?

我已经search了一种方法来调整在Java中的数组,但我找不到在保持当前元素的同时调整数组大小的方法。

我发现代码如int[] newImage = new int[newWidth]; ,但是这会删除之前存储的元素。

我的代码基本上会这样做:每当添加一个新的元素时,数组大1 。 我认为这可以用dynamic编程来完成,但我不知道如何实现它。

你不能用Java调整数组的大小。 你需要:

  1. 创build一个所需大小的新数组,并使用java.lang.System.arraycopy(...);将原始数组中的内容复制到新数组中java.lang.System.arraycopy(...);

  2. 使用java.util.ArrayList<T>类,当你需要增大数组的时候,它会为你做这个。 它很好地封装了你在你的问题中描述的内容。

  3. 使用java.util.Arrays.copyOf(...)方法返回一个更大的数组,其中包含原始数组的内容。

不好,但工作:

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

如前所述,去与ArrayList

你可以使用ArrayList来为你做这个工作。

这里有几个方法来做到这一点。


方法1: System.arrayCopy()

从指定的源数组中复制指定位置的数组到指定的目标数组的位置。 数组组件的子序列从src引用的源数组复制到dest引用的目标数组。 复制的组件数等于length参数。 源数组中srcPos到srcPos + length-1位置的组件分别被复制到destPos到destPos + length-1的位置。

 Object[] arr = new Object[5]; // initialize elements Object[] largerArr = new Object[10]; System.arrayCopy(arr, 0, largerArr, 0, arr.length(); 

方法2: Arrays.copyOf()

复制指定的数组,使用空值截断或填充(如有必要),使副本具有指定的长度。 对于在原始数组和复制中都有效的所有索引,这两个数组将包含相同的值。 对于在副本中有效但不是原始副本的索引,副本将包含空值。 当且仅当指定的长度大于原始数组的长度时,这样的索引才会存在。 结果数组与原始数组完全相同。

 Object[] arr = new Object[5]; // initialize elements Object[] largerArr = Arrays.copyOf(arr, 10); 

请注意,此方法通常在幕后使用System.arrayCopy()


方法3: ArrayList

List接口的可resize的实现。 实现所有可选的列表操作,并允许所有元素,包括null。 除了实现List接口之外,该类还提供了一些方法来处理内部用来存储列表的数组的大小。 (这个类大致相当于Vector,除了它是不同步的。)

ArrayList的function类似于数组,除了添加的元素多于它可以包含的元素时,它自动扩展。 它由一个数组支持 ,并使用Arrays.copyOf 。

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

你可以使用ArrayList而不是数组。 所以你可以添加n个元素

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

标准类java.util.ArrayList是可resize的数组,在添加新元素时增长。

无法更改数组大小。 但是您可以通过创build一个更大的数组来将一个数组的元素复制到另一个数组中。

如果Array已满,则build议创build两倍大小的Array,如果Array已满一半,则减lessArray以减半

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

调整数组的大小是不可能的。 但是,可以通过将原始数组复制到新数组来更改数组的大小,并保留当前元素。 通过删除元素并resize,也可以减小数组的大小。

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

是的,这是可能的

这里有两个解决scheme,但是抓住运行下面代码的性能差异

Java列表快450倍,但内存重20倍!

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