【问题标题】:How can I initialize an ArrayList with all zeroes in Java?如何在 Java 中用全零初始化 ArrayList?
【发布时间】:2011-04-08 20:54:42
【问题描述】:

看起来arraylist 没有做好预调整的工作:

// presizing 

ArrayList<Integer> list = new ArrayList<Integer>(60);

之后当我尝试访问它时:

list.get(5) 

它不是返回 0,而是抛出 IndexOutOfBoundsException: Index 5 out of bounds for length 0

有没有办法像 C++ 那样将所有元素初始化为精确大小的 0?

【问题讨论】:

  • 该构造函数的 Javadoc 指定它创建一个“空列表”。它正在做它的工作。

标签: java collections


【解决方案1】:

传递给构造函数的整数代表它的初始容量,即在需要调整其内部数组大小之前它可以容纳的元素数量(与初始元素数量无关)在列表中)。

要初始化一个包含 60 个零的列表:

List<Integer> list = new ArrayList<Integer>(Collections.nCopies(60, 0));

如果您想创建一个包含 60 个不同对象的列表,您可以使用带有 Supplier 的 Stream API,如下所示:

List<Person> persons = Stream.generate(Person::new)
                             .limit(60)
                             .collect(Collectors.toList());

【讨论】:

  • 这比我的解决方案要好得多(即使是我更新的解决方案也确实有效,呵呵)。我建议不要用它创建一个新的ArrayList,而是简单地编程到List。当然,这是留给 OP 的决定。
  • nCopies 返回的列表是不可变的,因此创建一个新的ArrayList 可能是个好主意。
  • 请注意,当将nCopies 与复杂对象一起使用时,集合不会用 60 个不同的对象实例化,而是用同一个对象实例化 60 次。所以只能将其用于基元。
  • @membersound,我可以想到nCopies 对引用类型有用的许多场景:不可变对象,例如字符串、空对象模式、枚举常量……无论如何,我更新了答案具有创建 60 个不同对象的解决方案。
  • @aioobe 我知道在很多情况下 ncopies 很有用。我只是想添加这个,因为我尝试使用可变对象的 ncopies 并且很惊讶它没有像我预期的那样工作。以防万一有人尝试相同的任务。不过感谢您的更新!
【解决方案2】:
// apparently this is broken. Whoops for me!
java.util.Collections.fill(list,new Integer(0));

// this is better
Integer[] data = new Integer[60];
Arrays.fill(data,new Integer(0));
List<Integer> list = Arrays.asList(data);

【讨论】:

  • 这只会用现有条目填充列表。它不会根据需要使用元素对其进行初始化。
  • 这不会用 60 个零填充列表。
  • 即使它会创建 60 个不需要创建任何对象的对象。
  • @Frost:你会得到一个IndexOutOfBoundsExceptionList&lt;Integer&gt; list = new ArrayList&lt;Integer&gt;(60); Collections.fill(list, new Integer(0)); list.get(5);
  • Arrays.asList 产生一个不允许添加或删除的List,因此它与OP想要的并不完全相同。如果您只需要set 就可以了,但在这种情况下您最好只使用数组。
【解决方案3】:

Java 8 实现(用60 零初始化的列表)

List<Integer> list = IntStream.of(new int[60])
                    .boxed()
                    .collect(Collectors.toList());
  • new int[N] - 创建一个用零和长度 N 填充的数组
  • boxed() - 每个元素都装箱为一个整数
  • collect(Collectors.toList()) - 收集流的元素

【讨论】:

    【解决方案4】:

    您传递的 60 只是内部存储的初始容量。它暗示了您认为它可能有多大,但当然它不受此限制。如果您需要预设值,您必须自己设置它们,例如:

    for (int i = 0; i < 60; i++) {
        list.add(0);
    }
    

    【讨论】:

      【解决方案5】:

      不是这样的。 ArrayList 只是使用数组作为内部替代。如果添加超过 60 个元素,则底层数组将被扩展。如何向这个数组添加尽可能多的 RAM 元素。

      【讨论】:

        猜你喜欢
        • 2011-05-28
        • 2018-04-28
        • 2016-11-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-07
        相关资源
        最近更新 更多