扩展数组?

时间:2011-12-08 22:54:57

标签: java

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

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()被调用时,新tempArray的大小与OrigArray相同{1}}然后保留OrigArrayOrigArray再次使用size+1宣布,然后将tempArray复制回新的OrigArray。这对我来说很有意义,但我一直在走出异常?

7 个答案:

答案 0 :(得分:14)

该方法不会更改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

编辑:如果您真正想要的是知道如何合理地实现您要求的功能,您可以使用@ÓscarLópez所说的并使用ArrayList。

答案 1 :(得分:6)

你想要手工完成的事情,它几乎是ArrayList为你做的事情 - 而是使用那个类。

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

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

答案 2 :(得分:2)

不,这不是一种有效的方法。你在做什么实际上是

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 ...()方法)背后的数据,并且您不希望一次只扩展一个元素,创建和复制数组是昂贵的。

答案 3 :(得分:0)

您的方法无法正常工作,因为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

答案 4 :(得分:0)

此:

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

基本上等同于:

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

因为第二项任务完全取代第一项。 OrigArray最终会与tempArray的尺寸相同,因此尺寸与原来相同。

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

答案 5 :(得分:0)

看看System.arraycopy - 它将一个数组复制到另一个数组(你也可以自己循环执行此操作,但arraycopy稍快一点)。因此,一般模式是创建一个比第一个更大的新数组,然后将第一个元素复制到更大的元素中,然后更新你的字段/变量以指向这个新的更大的数组。

答案 6 :(得分:0)

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