我必须在内存中保留数千个字符串,以便在Java中串行访问。我应该把它们存储在数组中还是应该使用某种列表?
由于数组将所有数据保存在一个连续的内存块中(与list不同),使用数组存储数千个字符串会导致问题吗?
我必须在内存中保留数千个字符串,以便在Java中串行访问。我应该把它们存储在数组中还是应该使用某种列表?
由于数组将所有数据保存在一个连续的内存块中(与list不同),使用数组存储数千个字符串会导致问题吗?
当前回答
不,因为从技术上讲,数组只存储对字符串的引用。字符串本身被分配到不同的位置。对于上千个项目,我会说列表会更好,它更慢,但它提供了更多的灵活性,更容易使用,特别是如果你要调整它们的大小。
其他回答
既然这里已经有了很多好的答案,我想给你一些其他的实际观点的信息,这是插入和迭代性能的比较:Java中的基元数组与链表。
这是实际的简单性能检查。因此,结果将取决于机器的性能。
用于此的源代码如下:
import java.util.Iterator;
import java.util.LinkedList;
public class Array_vs_LinkedList {
private final static int MAX_SIZE = 40000000;
public static void main(String[] args) {
LinkedList lList = new LinkedList();
/* insertion performance check */
long startTime = System.currentTimeMillis();
for (int i=0; i<MAX_SIZE; i++) {
lList.add(i);
}
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
System.out.println("[Insert]LinkedList insert operation with " + MAX_SIZE + " number of integer elapsed time is " + elapsedTime + " millisecond.");
int[] arr = new int[MAX_SIZE];
startTime = System.currentTimeMillis();
for(int i=0; i<MAX_SIZE; i++){
arr[i] = i;
}
stopTime = System.currentTimeMillis();
elapsedTime = stopTime - startTime;
System.out.println("[Insert]Array Insert operation with " + MAX_SIZE + " number of integer elapsed time is " + elapsedTime + " millisecond.");
/* iteration performance check */
startTime = System.currentTimeMillis();
Iterator itr = lList.iterator();
while(itr.hasNext()) {
itr.next();
// System.out.println("Linked list running : " + itr.next());
}
stopTime = System.currentTimeMillis();
elapsedTime = stopTime - startTime;
System.out.println("[Loop]LinkedList iteration with " + MAX_SIZE + " number of integer elapsed time is " + elapsedTime + " millisecond.");
startTime = System.currentTimeMillis();
int t = 0;
for (int i=0; i < MAX_SIZE; i++) {
t = arr[i];
// System.out.println("array running : " + i);
}
stopTime = System.currentTimeMillis();
elapsedTime = stopTime - startTime;
System.out.println("[Loop]Array iteration with " + MAX_SIZE + " number of integer elapsed time is " + elapsedTime + " millisecond.");
}
}
表现结果如下:
首先,有必要澄清一下,您是指经典的compp sci数据结构意义上的“列表”(即链表),还是指java.util.List?如果你指的是java.util。List,它是一个接口。如果你想使用数组,只要使用数组列表实现,你就会得到类似数组的行为和语义。问题解决了。
如果你指的是数组和链表,这是一个稍微不同的参数,我们回到大O(如果这是一个不熟悉的术语,这里有一个简单的英语解释。
数组;
随机存取:O(1); 插入:O (n); 删除:O (n)。
链表:
随机存取:O(n); 插入:O (1); 删除:O(1)。
你可以选择最适合调整数组大小的方法。如果你调整大小,插入和删除很多,那么链表可能是一个更好的选择。如果随机访问很少,情况也是如此。你提到了串行访问。如果你主要做串行访问,很少修改,那么你选择哪一个可能都不重要。
链表的开销略高,因为正如您所说,您正在处理潜在的不连续内存块和(有效地)指向下一个元素的指针。但是,除非您要处理数百万个条目,否则这可能不是一个重要因素。
List是java 1.5及以上版本的首选方式,因为它可以使用泛型。数组不能有泛型。数组也有预定义的长度,不能动态增长。初始化一个大数组并不是一个好主意。 ArrayList是用泛型声明数组的方式,它可以动态增长。 但如果删除和插入使用得更频繁,那么链表是使用最快的数据结构。
请记住,ArrayList封装了一个数组,因此与使用原始数组相比没有什么区别(除了在java中使用List更容易)。
选择数组而不是数组列表的唯一有意义的情况是,当你存储基本类型时,比如byte、int等,你需要通过使用基本类型数组获得特定的空间效率。
数组更快-所有内存都是预先分配的。