在Java中保留当前元素的同时调整数组的大小?
我已经search了一种方法来调整在Java中的数组,但我找不到在保持当前元素的同时调整数组大小的方法。
我发现代码如int[] newImage = new int[newWidth];
,但是这会删除之前存储的元素。
我的代码基本上会这样做:每当添加一个新的元素时,数组大1 。 我认为这可以用dynamic编程来完成,但我不知道如何实现它。
你不能用Java调整数组的大小。 你需要:
-
创build一个所需大小的新数组,并使用
java.lang.System.arraycopy(...);
将原始数组中的内容复制到新数组中java.lang.System.arraycopy(...);
-
使用
java.util.ArrayList<T>
类,当你需要增大数组的时候,它会为你做这个。 它很好地封装了你在你的问题中描述的内容。 -
使用
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(); } }