1. 使用纯Java移除List中的null

Java集合框架提供了两种简单粗暴的方案来移除List中的所有null元素:

方案一:while循环

@Test
public void givenListContainsNulls_whenRemovingNullsWithPlainJava_thenCorrect() {
    List<Integer> list = Lists.newArrayList(null, 1, null);
    while (list.remove(null));  // 循环直到移除所有null

    assertThat(list, hasSize(1));
}

⚠️ 注意:此方法会直接修改原始List

方案二:removeAll方法

@Test
public void givenListContainsNulls_whenRemovingNullsWithPlainJavaAlternative_thenCorrect() {
    List<Integer> list = Lists.newArrayList(null, 1, null);
    list.removeAll(Collections.singleton(null));  // 移除所有null元素

    assertThat(list, hasSize(1));
}

✅ 优点:代码简洁
❌ 缺点:同样会修改原始List

2. 使用Google Guava移除List中的null

Guava提供了更函数式的处理方式,特别适合需要链式操作的场景:

修改原始List

@Test
public void givenListContainsNulls_whenRemovingNullsWithGuavaV1_thenCorrect() {
    List<Integer> list = Lists.newArrayList(null, 1, null);
    Iterables.removeIf(list, Predicates.isNull());  // 移除所有null元素

    assertThat(list, hasSize(1));
}

创建新List(不修改原始数据)

@Test
public void givenListContainsNulls_whenRemovingNullsWithGuavaV2_thenCorrect() {
    List<Integer> list = Lists.newArrayList(null, 1, null, 2, 3);
    List<Integer> listWithoutNulls = Lists.newArrayList(
      Iterables.filter(list, Predicates.notNull()));  // 过滤null并创建新List

    assertThat(listWithoutNulls, hasSize(3));
}

✅ 优势:

  • 支持函数式编程风格
  • 可选择是否修改原始数据
  • 代码可读性高

3. 使用Apache Commons Collections移除List中的null

Apache Commons Collections提供了类似的函数式解决方案:

@Test
public void givenListContainsNulls_whenRemovingNullsWithCommonsCollections_thenCorrect() {
    List<Integer> list = Lists.newArrayList(null, 1, 2, null, 3, null);
    CollectionUtils.filter(list, PredicateUtils.notNullPredicate());  // 过滤null

    assertThat(list, hasSize(3));
}

⚠️ 注意:此方法会直接修改原始List
✅ 特点:

  • 代码简洁
  • 与Guava风格类似
  • 适合已使用Commons Collections的项目

4. 使用Java 8 Lambda表达式移除List中的null

Java 8提供了最现代的解决方案,支持并行处理:

并行流处理

@Test
public void givenListContainsNulls_whenFilteringParallel_thenCorrect() {
    List<Integer> list = Lists.newArrayList(null, 1, 2, null, 3, null);
    List<Integer> listWithoutNulls = list.parallelStream()  // 并行流处理
      .filter(Objects::nonNull)  // 过滤null
      .collect(Collectors.toList());
}

串行流处理

@Test
public void givenListContainsNulls_whenFilteringSerial_thenCorrect() {
    List<Integer> list = Lists.newArrayList(null, 1, 2, null, 3, null);
    List<Integer> listWithoutNulls = list.stream()  // 串行流处理
      .filter(Objects::nonNull)  // 过滤null
      .collect(Collectors.toList());
}

使用removeIf方法

@Test
public void givenListContainsNulls_whenRemovingNullsWithRemoveIf_thenCorrect() {
    List<Integer> listWithoutNulls = Lists.newArrayList(null, 1, 2, null, 3, null);
    listWithoutNulls.removeIf(Objects::isNull);  // 直接移除null

    assertThat(listWithoutNulls, hasSize(3));
}

✅ Java 8方案优势:

  • 代码最简洁
  • 支持并行处理提升性能
  • 函数式风格更现代
  • removeIf直接修改原始List,stream方案创建新List

5. 总结

本文对比了四种移除List中null元素的方案:

方案 是否修改原List 代码简洁度 性能特点 适用场景
纯Java ⭐⭐ 基础性能 无依赖的简单场景
Google Guava 可选 ⭐⭐⭐ 良好 已使用Guava的项目
Apache Commons ⭐⭐⭐ 良好 已使用Commons的项目
Java 8 Lambda 可选 ⭐⭐⭐⭐ 最佳(支持并行) Java 8+环境推荐首选

💡 实践建议:

  • 新项目优先使用Java 8 Lambda方案
  • 已使用第三方库的项目可保持技术栈一致性
  • 需要修改原List时选择removeIf或Guava/Commons方案
  • 需要保留原数据时选择stream()或Guava的filter方案

所有示例代码可在GitHub项目中获取,这是一个Maven项目,导入即可运行。


原始标题:Baeldung

« 上一篇: Baeldung周报22期
» 下一篇: Java 学习指南