扩展数组?

我知道你不能动态扩展普通数组,但这是一种有效的方法吗?

public int size = 0; public String[] OrigArray = new String[size+1]; public void expand(){ String[] tempArray = new String[size+1]; tempArray = (String[])OrigArray.clone(); OrigArray = new String[size+1]; OrigArray = (String[])tempArray.clone(); size++; } 

我知道比尝试使用普通数组要好得多的方法,但我想首先使用普通数组来解决这个问题。

我的愿望是它从OrigArray开始是0 + 1(所以1)并且当调用expand()时,新的tempArrayOrigArray大小相同,然后持有OrigArrayOrigArray再次以size+1声明size+1然后将tempArray复制回新尺寸的OrigArray 。 这对我来说很有意义,但我一直在走出exception?

该方法不会更改OrigArray的值; 它所做的只是在其中存储克隆的克隆,因此实际上不会更改该值。

我想你想要的是这个:

 public void expand() { String[] newArray = new String[OrigArray.length + 1]; System.arraycopy(OrigArray, 0, newArray, 0, OrigArray.length); //an alternative to using System.arraycopy would be a for-loop: // for(int i = 0; i < OrigArray.length; i++) // newArray[i] = OrigArray[i]; OrigArray = newArray; } 

这将创建一个大小比OrigArray大1的数组,将OrigArray的内容复制到其中并将该数组分配给OrigArray。 除非你想记住expand()被调用了多少次,否则没有理由拥有变量size

编辑:如果您真正想要的是知道一种方法来合理地实现您要求的function,您可以使用@ÓscarLópez所说的并使用ArrayList。

你想要手工完成什么,它几乎就是ArrayList为你所做的 – 而是使用那个类。

在引擎盖下, ArrayList使用Object[]在一定容量约束下存储项目。 填充数组时(添加新项目),将创建一个大小加倍的新数组,并在其中复制原始数组中的所有项目。 所有这些都是自动发生的,对程序员来说是透明的。

鉴于在示例代码中您存储了一个对象数组(字符串),如果使用ArrayList存储它们,性能上几乎没有差别,因此没有真正的理由重新发明轮子!

不,这不是一种有效的方法。 你到底在做什么

 First create a new larger array Throw away the newly created array and copy the original array Create year another new array with larger size Throw away the newly created array and clone the already cloned array again 

对于非原始类型,我认为您想使用ArrayList

但是,如果要为原始类型构建它,这就是你要这样做的方法

 public int size = 0; public int[] origArray = new int[size+1]; public void expand(){ int[] tempArray = new int[size+1]; System.arrayCopy(origArray, 0, tempArray, 0, size); origArray = tempArray; size++; } 

您可能希望隐藏访问器( get …()方法)背后的数据,并且您不希望一次只将一个元素扩展到一个元素,创建和复制数组的成本很高。

您的方法将无法工作,因为clone()只会将数组重新分配给原始大小。 我建议使用

 System.arraycopy(OrigArray, 0, tempArray, 0, OrigArray.length); 

代替。

此外,最有效的方法是使用ArrayList ,因为它们实现了几乎相同的东西,但是清理了很多代码。

唯一的问题是当你需要得到值的类型的常规数组时,你必须这样做:

 String[] asArr = new String[OrigArray.length]; for(int i = 0; i < OrigArray.length; i++) asArr[i] = OrigArray.get(i); 

这是ArrayList的Javadoc:

http://docs.oracle.com/javase/1.4.2/docs/api/java/util/ArrayList.html

这个:

 OrigArray = new String[size+1]; OrigArray = (String[])tempArray.clone(); 

基本上相当于这个:

 OrigArray = (String[])tempArray.clone(); 

因为第二个任务完全取代了第一个任务。 OrigArray最终将具有与tempArray相同的大小,因此与原来的大小相同。

如果要将元素复制到现有数组中,则必须编写循环,或者使用java.lang.System.arrayCopy(...)为您处理循环; 但是在数组上调用clone()将始终创建一个新数组,因此无济于事。

看一下System.arraycopy – 它将一个数组复制到另一个数组(你也可以在循环中自己做这个,尽管arraycopy有点快)。 因此,一般模式是创建一个比第一个更大的新数组,然后将第一个元素复制到更大的元素中,然后更新您的字段/变量以指向这个新的更大的数组。

在存储器中不断地构造和破坏对象是昂贵且缓慢的。 我会编写一个存储一些额外空间(可能是3-5个额外项目)的类,类似于List的工作方式,并且在查询大小时只输出使用的空间,并且只有在超出此缓冲区空间时才会展开。 这可以大大提高性能。