在Java中执行可调整大小的数组的最佳方法是什么?我尝试使用Vector,但是当你进行插入时,它会移动所有元素,我需要一个可以增长但元素保持不变的数组。我确信这有一个简单的答案,但我仍然不太确定。
答案 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)。列表结构已满并且必须将新项目添加到列表中。然后结构首先创建一个新数组,该数组可以包含旧元素以及必须添加到列表中的新元素。
列表界面有不同的实现,都有优点/缺点,你应该选择最好的解决你的问题集。下面我将尝试简要总结何时使用哪种实现:
size, isEmpty, get, set, iterator, and listIterator
操作时,应该使用此实现。 add
操作以分摊的常量时间运行,即添加n个元素需要O(n)时间。我认为您应该在执行更多查找(get()
)时使用此实现,然后将项目添加到列表(add()
)。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)
答案 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;