我必须在内存中保留数千个字符串,以便在Java中串行访问。我应该把它们存储在数组中还是应该使用某种列表?
由于数组将所有数据保存在一个连续的内存块中(与list不同),使用数组存储数千个字符串会导致问题吗?
我必须在内存中保留数千个字符串,以便在Java中串行访问。我应该把它们存储在数组中还是应该使用某种列表?
由于数组将所有数据保存在一个连续的内存块中(与list不同),使用数组存储数千个字符串会导致问题吗?
当前回答
在存储字符串对象的情况下,数组还是列表的选择并不那么重要(考虑到性能)。因为数组和列表存储的都是字符串对象引用,而不是实际对象。
如果字符串的数量几乎是常数,则使用数组(或ArrayList)。但如果数字变化太大,那么你最好使用LinkedList。 如果有(或将会)需要在中间添加或删除元素,那么你当然必须使用LinkedList。
其他回答
我写了一个比较数组列表和数组的基准测试。在我的老式笔记本电脑上,遍历5000个元素的数组列表1000次的时间比等效的数组代码慢了大约10毫秒。
所以,如果你什么都不做,只是迭代列表,而且你做了很多,那么也许它值得优化。否则,我会使用列表,因为当你需要优化代码时,它会让你更容易。
注意:我确实注意到,使用for String s: stringsList比使用老式的for循环访问列表要慢50%左右。去图…这是我计时的两个函数;数组和列表由5000个随机(不同的)字符串填充。
private static void readArray(String[] strings) {
long totalchars = 0;
for (int j = 0; j < ITERATIONS; j++) {
totalchars = 0;
for (int i = 0; i < strings.length; i++) {
totalchars += strings[i].length();
}
}
}
private static void readArrayList(List<String> stringsList) {
long totalchars = 0;
for (int j = 0; j < ITERATIONS; j++) {
totalchars = 0;
for (int i = 0; i < stringsList.size(); i++) {
totalchars += stringsList.get(i).length();
}
}
}
我同意在大多数情况下,您应该选择数组列表的灵活性和优雅性,而不是数组——在大多数情况下,它对程序性能的影响可以忽略不计。
然而,如果你对软件图形渲染或自定义虚拟机进行很少结构变化(没有添加和删除)的频繁迭代,我的顺序访问基准测试表明,数组列表比我的系统上的数组慢1.5倍(在我一岁的iMac上是Java 1.6)。
一些代码:
import java.util.*;
public class ArrayVsArrayList {
static public void main( String[] args ) {
String[] array = new String[300];
ArrayList<String> list = new ArrayList<String>(300);
for (int i=0; i<300; ++i) {
if (Math.random() > 0.5) {
array[i] = "abc";
} else {
array[i] = "xyz";
}
list.add( array[i] );
}
int iterations = 100000000;
long start_ms;
int sum;
start_ms = System.currentTimeMillis();
sum = 0;
for (int i=0; i<iterations; ++i) {
for (int j=0; j<300; ++j) sum += array[j].length();
}
System.out.println( (System.currentTimeMillis() - start_ms) + " ms (array)" );
// Prints ~13,500 ms on my system
start_ms = System.currentTimeMillis();
sum = 0;
for (int i=0; i<iterations; ++i) {
for (int j=0; j<300; ++j) sum += list.get(j).length();
}
System.out.println( (System.currentTimeMillis() - start_ms) + " ms (ArrayList)" );
// Prints ~20,800 ms on my system - about 1.5x slower than direct array access
}
}
数组-当我们必须实现更快的结果获取时,它总是更好的
列表——执行插入和删除的结果,因为它们可以在O(1)中完成,这也提供了方便地添加、获取和删除数据的方法。更容易使用。
但是始终记住,当数据存储在数组中的索引位置是已知的时,数据的抓取将是快速的。
这可以通过对数组排序很好地实现。因此,这增加了获取数据的时间(即;存储数据+排序数据+寻找数据所在的位置)。因此,这增加了从数组中获取数据的额外延迟,即使它们可能擅长更快地获取数据。
因此,这可以用三元数据结构或三元数据结构来解决。如上所述,树数据结构在搜索数据时非常有效,对特定单词的搜索可以在O(1)量级上完成。当时间紧迫时;如果你必须快速搜索和检索数据,你可以使用三种数据结构。
如果你希望你的内存空间消耗更少,你希望有一个更好的性能,那么使用三元数据结构。这两个都适合存储大量的字符串(例如;比如字典里的单词)。
数组建议你在任何地方使用它们而不是列表,特别是在你知道项目的数量和大小不会改变的情况下。
参见Oracle Java最佳实践:http://docs.oracle.com/cd/A97688_16/generic.903/bp/java.htm#1007056
当然,如果需要多次从集合中添加和删除对象,则使用简单列表。
“数千”不是一个很大的数字。几千个段落长度的字符串大小大约是几兆字节。如果您想要做的只是连续访问这些,请使用不可变的单链表。