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项目,导入即可运行。