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

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


当前回答

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

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

图片来源:https://github.com/egonSchiele/grokking_algorithms

这取决于实现。基元类型数组可能比ArrayList更小更高效。这是因为数组将直接将值存储在一个连续的内存块中,而最简单的ArrayList实现将存储指向每个值的指针。特别是在64位平台上,这可能会产生巨大的差异。

当然,对于这种情况,jvm实现有可能有一个特殊情况,在这种情况下,性能将是相同的。

请记住,ArrayList封装了一个数组,因此与使用原始数组相比没有什么区别(除了在java中使用List更容易)。

选择数组而不是数组列表的唯一有意义的情况是,当你存储基本类型时,比如byte、int等,你需要通过使用基本类型数组获得特定的空间效率。