有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

ArrayList中的java初始容量

我需要创建一个ArrayList,我预先知道这个数组的最大大小不会超过5个元素

我想从社区了解initailCapacity将大小指定为5是否会带来性能优势

List<String> list = new ArrayList<>(5);

或者

List<String> list = new ArrayList<>();

哪一个更好


共 (5) 个答案

  1. # 1 楼答案

    这取决于用例。假设您已经知道一定数量的对象(在本例中为字符串对象)将被存储,那么如果您在创建ArrayList时指定其大小,则会在该步骤分配内存

    List<String> list = new ArrayList<>(5);
    

    然后,一旦元素被填充,ArrayList的大小将随着添加更多对象而动态扩展。假设您确实要向ArrayList添加50个元素,那么将初始容量指定为50,这将导致分配那么多空间。这将是一种更有效的方法,因为在初始化之后,您不会动态分配多达50个元素的内存。在ArrayList展开时分配内存会影响性能。同时,如果指定了较大的初始大小,则会浪费宝贵的内存空间

  2. # 2 楼答案

    如果您确实希望列表通常至少包含一些元素(但不超过5个),那么是的,将初始容量设置为5可能是最有效的方法

    后备数组的延迟实例化

    然而,如果最常见/预期的情况是,甚至没有一个项目被添加到列表中,那么没有任何指定初始容量的构造函数可能更有效。这是因为(假设使用了较新的JDK版本),ArrayList根本不会分配任何支持数组,只会使用在所有空的、默认构造的ArrayList之间共享的引用。只有当你开始添加项目时,它才会真正分配内存

    将第一个元素添加到ArrayList时,将创建一个新的支持数组。新数组的默认大小为10


    要了解最初使用的是对支持数组的共享引用,您可以查看OpenJDK的github,例如,您可以找到no-args构造函数here的实现。情况如下:

    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    

    备份数组(elementData)被分配到的引用在文件中被声明为更高级别,如下所示:

    /**
     * Shared empty array instance used for default sized empty instances. We
     * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
     * first element is added.
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    

    这不仅发生在OpenJDK中,也发生在Oracle的JDK中。至少,我电脑上的版本是这样的。我不知道是否有任何容易找到的Oracle源代码链接,但是OpenJDK源代码更容易在网上找到

  3. # 3 楼答案

    是的,它会提高性能,因为默认值为10的内存不会被占用太多

  4. # 4 楼答案

    来自ArrayList。爪哇

    /**
     * Default initial capacity.
     */
    private static final int DEFAULT_CAPACITY = 10;
    

    默认容量(不提供时使用)为10。因此,指定5的大小将意味着使用更少的内存

    如果你知道一个更轻量级的数组,也许你会有一个更轻量级的选择

  5. # 5 楼答案

    是的,它会提高性能,但只会提高一小部分

    如果你知道列表总是那么长,那么最好将其设置为特定的长度,但这样的使用往往很少,所以不应该是一个常见的问题

    此外,如果它是一个由5个成员组成的列表,那么你最好只创建一个包含5个字段的新对象。这将使处理这些数据更容易、更快,因为不需要搜索列表