You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Stream过滤对象报NPE问题修复及筛选规则实现

问题原因

当前代码抛出空指针、逻辑不符合预期的核心问题如下:

  • 筛选逻辑写了两个串行的filter,是必须同时满足的与关系:第一个filter只保留objId == null的对象,第二个filter直接对null值调用contains方法,必然触发空指针;完全没有实现“满足任意一个条件即可保留”的或逻辑
  • 直接用字符串contains方法做匹配会出现误判:比如objId值为"7,84,3"、sections包含"8"时,会错误匹配到"84"中的子串"8",不符合拆分后元素精确比对的要求
  • getData方法的测试数据赋值顺序错误:给objs1设置"1,2,3"加入列表后,又重新给objs1赋值"4,5,6"再加入objs2,导致objs2、objs3的objId属性根本没有被赋值,默认是null,测试数据本身不符合预期
  • 没有覆盖sections为null/空串的边界场景,不满足定义的场景4规则
修正后代码

修正点包括:

  1. 整合筛选逻辑为单个filter,实现空objId直接保留、非空objId做拆分后精确交集匹配的或逻辑
  2. 所有字符串拆分后做元素精确相等判断,避免子串误匹配
  3. 增加sections空值兜底逻辑,符合边界场景规则
  4. 修正测试数据的赋值错误
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

public class TestStream {

    private List<Objs> getData() {
        List<Objs> objects = new ArrayList<>();
        Objs objs1 = new Objs();
        Objs objs2 = new Objs();
        Objs objs3 = new Objs();
        Objs objs4 = new Objs();
        // 修正赋值顺序:每个对象设值完成后再加入列表
        objs1.setObjId("1,2,3");
        objects.add(objs1);
        objs2.setObjId("4,5,6");
        objects.add(objs2);
        objs3.setObjId("7,84,3");
        objects.add(objs3);
        objs4.setObjId(null);
        objects.add(objs4);
        return objects;
    }

    private List<Objs> test () {
        // 模拟sections入参,实际使用时替换为外部传入值即可
        String sectionStr = "2,8";
        // 预处理sections:空值/空串时转为空集合,符合场景4规则
        Set<String> sectionSet;
        if (sectionStr == null || sectionStr.trim().isEmpty()) {
            sectionSet = new HashSet<>();
        } else {
            sectionSet = Arrays.stream(sectionStr.split(","))
                    .map(String::trim)
                    .collect(Collectors.toSet());
        }

        List<Objs> objects = getData();
        List<Objs> result = objects.stream()
                .filter(object -> {
                    String objId = object.getObjId();
                    // 条件1:objId为null或空串,直接保留
                    if (objId == null || objId.trim().isEmpty()) {
                        return true;
                    }
                    // sections为空集合时,非空objId直接不保留,符合场景4规则
                    if (sectionSet.isEmpty()) {
                        return false;
                    }
                    // 条件2:拆分objId后和sections集合做精确匹配,有交集则保留
                    Set<String> objIdSet = Arrays.stream(objId.split(","))
                            .map(String::trim)
                            .collect(Collectors.toSet());
                    return objIdSet.stream().anyMatch(sectionSet::contains);
                })
                .skip(0)
                .limit(3) // 按需求设置每页3条
                .collect(Collectors.toList());
        return result;
    }

    public static void main(String[] args) {
        TestStream testStream= new TestStream();
        List<Objs> result = testStream.test();
        // 打印结果方便验证
        result.forEach(obj -> System.out.println("命中对象objId:" + obj.getObjId()));
    }

    class Objs {
        private String objId;
        public void setObjId(String id) { objId = id;}
        public String getObjId() { return objId;}
    }
}
逻辑验证说明
  • 场景1:objId为"1,2,3"、sections为"2,4"时,会匹配到共同元素"2",对象保留
  • 场景2:objId为"1,3"、sections为"2"时,无共同元素,对象过滤
  • 场景3:objId为null/空串时,无论sections是什么值,对象直接保留
  • 场景4:sections为null/空串时,只有objId为null/空串的对象会保留,其余全部过滤
  • 不会出现子串误匹配:比如objId为"7,84,3"、sections含"8"时,不会错误命中

内容的提问来源于stack exchange,提问作者pintekus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 22:15:48