1. 概述

本文将探讨在Java中初始化包含全null或全0值的ArrayList的多种方法。我们还可以根据需求灵活调整初始化值,例如填充其他数值或对象。

2. 使用for循环

遇到初始化ArrayList的需求时,最直观的解决方案就是使用for循环。这种方法简单直接,代码清晰:

ArrayList<Integer> arrayList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
    arrayList.add(null);
    // 或者添加0:arrayList.add(0);
}

我们创建一个空ArrayList,然后通过循环调用add()方法填充元素。

3. 使用ArrayList构造方法

另一种不太常见但高效的方法是利用ArrayList的构造函数。该构造函数接受一个Collection参数,并按迭代器返回的顺序创建包含指定集合元素的新列表。为实现目标,我们将结合Collections类的nCopies()方法

@Test
public void whenInitializingListWithNCopies_thenListIsCorrectlyPopulated() {
    // 初始化包含10个0的ArrayList
    ArrayList<Integer> list = new ArrayList<>(Collections.nCopies(10, 0));

    // 验证结果
    Assertions.assertEquals(10, list.size());
    Assertions.assertTrue(list.stream().allMatch(elem -> elem == 0));
}

我们验证列表大小是否正确,并使用Java Stream API的allMatch()确认所有元素均为目标值。

4. 使用Java Stream API

Stream不仅能用于验证,还能直接生成列表。通过Stream.generate()方法,我们可以基于Supplier创建无限流:

@Test
public void whenInitializingListWithStream_thenListIsCorrectlyPopulated() {
    
    // 生成包含10个0的列表
    ArrayList<Integer> listWithZeros = Stream.generate(() -> 0)
      .limit(10).collect(Collectors.toCollection(ArrayList::new));

    // 生成包含10个null的列表
    ArrayList<Object> listWithNulls = Stream.generate(() -> null)
      .limit(10).collect(Collectors.toCollection(ArrayList::new));

    // 验证结果
    Assertions.assertEquals(10, listWithZeros.size());
    Assertions.assertTrue(listWithZeros.stream().allMatch(elem -> elem == 0));

    Assertions.assertEquals(10, listWithNulls.size());
    Assertions.assertTrue(listWithNulls.stream().allMatch(Objects::isNull));
}

limit()方法限制流的大小,确保我们只获取指定数量的元素。

5. 使用IntStream

初始化数值列表时,IntStream是更专业的选择。作为BaseStream的子类,它提供了处理原始数值流的能力:

@Test
public void whenInitializingListWithIntStream_thenListIsCorrectlyPopulated() {
    // 创建包含10个0的ArrayList
    ArrayList<Integer> list = IntStream.of(new int[10])
      .boxed()
      .collect(Collectors.toCollection(ArrayList::new));

    // 验证结果
    Assertions.assertEquals(10, list.size());
    Assertions.assertTrue(list.stream().allMatch(elem -> elem == 0));
}

⚠️ 注意:此方法仅适用于数值初始化,无法用于填充null值。

6. 使用Arrays.asList

通过Arrays.asList()方法,我们可以将数组转换为列表。具体步骤如下:

  1. 创建数组
  2. 使用Arrays.fill()填充目标值
  3. 转换为列表
@Test
public void whenInitializingListWithAsList_thenListIsCorrectlyPopulated() {
    // 创建并填充数组
    Integer[] integers = new Integer[10];
    Arrays.fill(integers, 0);
    List<Integer> integerList = Arrays.asList(integers);

    // 验证结果
    Assertions.assertEquals(10, integerList.size());
    Assertions.assertTrue(integerList.stream().allMatch(elem -> elem == 0));
}

❌ 踩坑提示:Arrays.asList()返回的是固定大小的列表,尝试添加元素会抛出UnsupportedOperationException。解决方法:

// 转换为真正的ArrayList
List<Integer> integerList = new ArrayList<>(Arrays.asList(integers));

✅ 技巧:若需初始化null值,直接省略fill()步骤即可(数组默认初始化为null)。

7. 使用Vector类

Vector作为Java遗留类,与ArrayList类似但方法全同步。其优势在于可直接初始化指定大小的列表:

@Test
public void whenInitializingListWithVector_thenListIsCorrectlyPopulated() {
    // 初始化包含10个null的Vector
    List<Integer> integerList = new Vector<>() {{setSize(10);}};

    // 验证结果
    Assertions.assertEquals(10, integerList.size());
    Assertions.assertTrue(integerList.stream().allMatch(elem -> elem == null));
}

通过setSize()方法,Vector会自动填充null值。⚠️ 注意:此方法仅适用于null初始化。

8. 总结

本文介绍了初始化包含null0ArrayList的七种方法,涵盖从基础循环到高级Stream API的多种技术。选择建议:

  • ✅ 简单场景:for循环
  • ✅ 高效初始化:Collections.nCopies()
  • ✅ 灵活生成:Stream API
  • ✅ 数值专用:IntStream
  • ⚠️ 避免踩坑:注意Arrays.asList()的固定大小特性
  • ✅ 遗留系统:VectorsetSize()

所有示例代码可在GitHub仓库中获取。


原始标题:Initialize an ArrayList with Zeroes or Null in Java | Baeldung