如何使用Java Stream将列表中不匹配条件的元素置null并保持列表大小不变
实现方案
你之前用filter达不到预期的原因很直接:filter会把不满足断言的元素直接从流里扔掉,最终结果列表的长度天然会缩短,完全适配不了你要“保持列表长度不变、仅替换不符合条件的位置为null”的需求。
要实现这个效果,核心是换用map映射操作——这个操作不会丢弃流里的元素位置,只会对每个位置的元素做值转换,刚好匹配你的场景。
具体代码
确保你的Val类已经生成了标准的getName()方法,直接套用下面的Stream逻辑即可:
List<Val> valuesOut = values.stream() .map(val -> { // 兜底处理:原列表如果本身有null元素,不会触发空指针 if (val != null && "ABC".equals(val.getName())) { return val; } return null; }) .collect(Collectors.toList());
效果校验
拿你举的示例输入走一遍逻辑:
- 输入原列表4个元素,输出列表也严格保持4个元素的长度
- 位置为1的元素name是
ABC,保留原对象 - 位置为2的元素name是
DEF,替换为null - 位置3、4的元素name都是
ABC,全部保留原对象
最终输出和你预期的结果完全一致:[Val(name=ABC,value=val1), null, Val(name=ABC,value=val3), Val(name=ABC,value=val4)]
实操注意点
- 代码里把匹配常量
"ABC"写在equals左边,是为了规避元素name为null时的空指针问题,比写val.getName().equals("ABC")稳妥很多 - 如果你后续需要对结果列表做增删操作,建议把收集逻辑换成
collect(Collectors.toCollection(ArrayList::new)),避免部分JDK版本下Collectors.toList()返回的定长列表抛UnsupportedOperationException - 别和
filter的用法搞混:要裁剪元素数量的时候用filter,要保持元素数量只改每个位置的值的时候,才用map
很多人写Stream的时候会第一反应用
filter,其实只要想清楚操作对元素数量的影响,很容易就能选对接口。
内容的提问来源于stack exchange,提问作者AlanC
相关产品推荐
相关产品推荐

