我必须在内存中保留数千个字符串,以便在Java中串行访问。我应该把它们存储在数组中还是应该使用某种列表?

由于数组将所有数据保存在一个连续的内存块中(与list不同),使用数组存储数千个字符串会导致问题吗?


当前回答

在存储字符串对象的情况下,数组还是列表的选择并不那么重要(考虑到性能)。因为数组和列表存储的都是字符串对象引用,而不是实际对象。

如果字符串的数量几乎是常数,则使用数组(或ArrayList)。但如果数字变化太大,那么你最好使用LinkedList。 如果有(或将会)需要在中间添加或删除元素,那么你当然必须使用LinkedList。

其他回答

数组列表在内部使用数组对象来添加(或存储)对象 元素。换句话说,ArrayList由Array数据支持 结构。ArrayList的数组是可调整大小的(或动态的)。

Array比ArrayList快,因为ArrayList内部使用数组。如果我们可以直接在数组中添加元素,而间接地在数组中添加元素 数组通过数组列表总是直接机制比间接机制快。

在ArrayList类中有两个重载的add()方法:

add(Object):将一个对象添加到列表末尾。 add(int index, Object):将指定对象插入到列表的指定位置。

数组列表的大小如何动态增长?

public boolean add(E e)        
{       
     ensureCapacity(size+1);
     elementData[size++] = e;         
     return true;
}

An important point to note from the above code is that we are checking the capacity of the ArrayList, before adding the element. ensureCapacity() determines what is the current size of occupied elements and what is the maximum size of the array. If the size of the filled elements (including the new element to be added to the ArrayList class) is greater than the maximum size of the array then increase the size of the array. But the size of the array can not be increased dynamically. So what happens internally is new Array is created with the capacity

到 Java 6

int newCapacity = (oldCapacity * 3)/2 + 1;

(更新)来自Java 7

 int newCapacity = oldCapacity + (oldCapacity >> 1);

此外,旧数组中的数据被复制到新数组中。

数组列表中有开销方法这就是为什么数组比数组列表快。

如果提前知道数据有多大,那么使用数组会更快。

List更加灵活。你可以使用由数组支持的数组列表。

我不认为这对Strings有什么影响。字符串数组中连续的是对字符串的引用,字符串本身存储在内存中的随机位置。

数组与列表的区别在于基本类型,而不是对象。如果您预先知道元素的数量,并且不需要灵活性,那么由数百万个整数或双精度数组成的数组将比列表在内存和速度上更有效,因为它们确实是连续存储的,并且可以立即访问。这就是为什么Java仍然使用字符数组表示字符串,使用整数数组表示图像数据,等等。

在存储字符串对象的情况下,数组还是列表的选择并不那么重要(考虑到性能)。因为数组和列表存储的都是字符串对象引用,而不是实际对象。

如果字符串的数量几乎是常数,则使用数组(或ArrayList)。但如果数字变化太大,那么你最好使用LinkedList。 如果有(或将会)需要在中间添加或删除元素,那么你当然必须使用LinkedList。

我同意在大多数情况下,您应该选择数组列表的灵活性和优雅性,而不是数组——在大多数情况下,它对程序性能的影响可以忽略不计。

然而,如果你对软件图形渲染或自定义虚拟机进行很少结构变化(没有添加和删除)的频繁迭代,我的顺序访问基准测试表明,数组列表比我的系统上的数组慢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
    }
}