如何在Java中创建可调整大小的数组?

时间:2010-04-06 00:36:00

标签: java arrays implementation resizable

在Java中执行可调整大小的数组的最佳方法是什么?我尝试使用Vector,但是当你进行插入时,它会移动所有元素,我需要一个可以增长但元素保持不变的数组。我确信这有一个简单的答案,但我仍然不太确定。

11 个答案:

答案 0 :(得分:23)

作为替代方案,您可以使用ArrayList。它是List接口的可调整大小的数组实现。

用法(使用String):

List<String> myList = new ArrayList<String>();
myList.add("a");
myList.add("c");
myList.add("b");

订单就像你把它们放进去一样:a,c,b。

您还可以获得这样的单个项目:

String myString = myList.get(0);

这会给你第0个元素:“a”。

答案 1 :(得分:4)

像Sanjo指出的那样:“An array is a static datastructure, so they can't grow”。列表界面可以由array支持(例如凯文在ArrayList中指出的post)。列表结构已满并且必须将新项目添加到列表中。然后结构首先创建一个新数组,该数组可以包含旧元素以及必须添加到列表中的新元素。

列表界面有不同的实现,都有优点/缺点,你应该选择最好的解决你的问题集。下面我将尝试简要总结何时使用哪种实现:

不是线程安全的实现:

  • ArrayList:List接口的可调整大小的数组实现。当您在恒定时间内执行大量size, isEmpty, get, set, iterator, and listIterator操作时,应该使用此实现。 add操作以分摊的常量时间运行,即添加n个元素需要O(n)时间。我认为您应该在执行更多查找(get())时使用此实现,然后将项目添加到列表(add())。
  • LinkedList:此实现不是由数组备份,而是将节点“链接”在一起。在我看来,当您执行更多add()然后get()
  • 时,您应该使用此实现

线程安全实现:

请注意,这些列表实现不是thread - 安全,这意味着从多个线程访问它们时可以获得race conditions。如果你想使用来自多个线程的List实现,我会建议你研究java.util.concurrent包并使用该类的实现。

答案 2 :(得分:3)

A LinkedList

答案 3 :(得分:3)

您可能应该使用ArrayList而不是Vector,原因在其他答案中有解释。

然而......

  

我尝试使用Vector,但是当你进行插入时,我将需要一个可以增长但元素保持不变的数组。

执行insertElementAt(pos, elem)时,明确要求元素移位。如果您不希望移动元素,则应使用set(pos, elem)代替。或者,如果要在向量的末尾添加元素,也可以使用add(elem)

顺便提一下,前一段适用于List的所有实施,而不仅仅是Vector,但实施细节和效果因List种不同而异。

答案 4 :(得分:2)

查看ArrayList

答案 5 :(得分:1)

  

我尝试使用Vector,但是当你进行插入时,我将需要一个可以增长但元素保持不变的数组。

您可能希望使用ArrayList而不是Vector。

它们都提供相同的接口,您可以通过调用set(idx, element)来替换两个元素。这没有任何转变。但是它也不允许你增长数组:你只能在已占用的位置插入(不超过数组的当前大小),在最后添加新元素时必须使用add(element)。 / p>

ArrayList和Vector之间的区别在于Vector具有您很可能不需要的同步代码,这使得ArrayList更快一些。

答案 6 :(得分:1)

如果要在所有元素都已插入或删除后操作数组数据,有一种方法可以尝试创建LinkedList或ArrayList,只需调整大小,在数据输入完成后,可以将ArrayList传输到数组,然后通常做所有的数组。

答案 7 :(得分:1)

ArrayList和LinkedList

空间复杂性:

a)ArrayList: 每当你动态添加一个元素时,每当它达到最大大小时进行初始化和加倍,就会分配一块内存。

b)LinkedList: 它只在每次向列表中添加项目时分配内存。

运行时复杂性:

a)ArrayList: 与链表

相比,搜索速度更快,插入和删除速度更慢

b)LinkedList: 插入和删除速度更快,与数组列表相比搜索速度更慢

答案 8 :(得分:0)

使用ArrayList或LinkedList。

答案 9 :(得分:0)

无法在Java中动态调整数组大小。解决方案是使用ArrayList或创建另一个临时数组,然后分配它。

您可以找到有关ArrayList的教程,但是如果您只想使用Java自定义ResizableArray。就是这样但是不建议使用!它只是一个FAKE可调整大小的数组,当您创建太多对象时,堆内存将增加。这只是为了向您展示这个想法。

  • 界面
public interface Resizable<T> {

    void add(T data);
    int delete(int index);
    int size();
    void print();
}
  • 实施班
public class ResizeableImpl<T> implements Resizable<T> {

    private Object[] temp = null;
    private Object[] originals = new Object[0];

    @Override
    public void add(T data) {
        Object[] temp = new Object[originals.length+1];
        for (int i=0; i<originals.length; i++) {
            temp[i]=originals[i];
        }
        temp[originals.length]=data;
        originals=temp;
    }

    @Override
    public int delete(int index) {
        int success=0;
        switch (originals.length) {
            case 0: //No Data to delete
                success=0;
                break;
            case 1: //One Data is delete and so no data, too!
                originals = new Object[0];
                success = 1;
                break;
            default: //>=2
                int count=0;
                originals[index]=null;
                temp = new Object[originals.length-1];
                for (int i=0; i<originals.length; i++) {
                    if (originals[i]!=null)
                    temp[count++]=originals[i];
                }
                originals = temp;
                success = 1;
        }

        return success;
    }

    @Override
    public int size() {
        return originals.length;
    }

    @Override
    public void print() {
        StringBuilder sb = null;

        if (originals.length==0) {
            System.out.println("No data available!");
            return;
        }

        for (int i=0; i<originals.length; i++) {
            if (sb==null) {
                sb = new StringBuilder();
                sb.append(originals[i]);
            }
            else {
                sb.append(", "+originals[i]);
            }
        }
        sb.append(".");
        System.out.println(sb.toString());
    }
}
  • 主要方法
public class App {

    public static void main(String[] args) {
        //Program to interfaces, not implementations
        Resizable<Integer> obj = new ResizeableImpl<>();

        obj.add(13);
        obj.add(20);
        obj.add(17);
        obj.add(25);
        obj.add(100);
        obj.add(12);
        obj.print();

        int result = obj.delete(2); //This will delete 17.
        if (result==1) {
            System.out.println("Deletion is successful!");
        }
        obj.print();

        obj.delete(3); //This will delete 100.
        obj.print();
    }
}

输出

13, 20, 17, 25, 100, 12.
Deletion is successful!
13, 20, 25, 100, 12.
13, 20, 25, 12.

答案 10 :(得分:-3)

在Collections框架中使用精彩的类比使用数组更好。 但是如果你的问题是从“测验”的角度来看,这就是你应该做的。 创建自己的调整大小方法,例如:

  int[] oldArray = {1,2,3};

  int oldSize = java.lang.reflect.Array.getLength(oldArray);
  Class elementType = oldArray.getClass().getComponentType();
  Object newArray = java.lang.reflect.Array.newInstance(
         elementType,newSize);
  int preserveLength = Math.min(oldSize,newSize);
  if (preserveLength > 0)
      System.arraycopy (oldArray,0,newArray,0,preserveLength);

  oldArray = newArray;