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

如何用Java Stream获取满足login=peter且status=SLEEP的JSON的itemid

问题:通过Java Stream筛选符合条件的itemid值

项目已引入Jackson库并定义了对应POJO类,现有如下JSON数组数据,需要通过Java Stream获取满足以下条件的itemid值:数据中存在login为peter的worker,且该worker包含status为SLEEP的状态。尝试了以下代码但未成功:

JSON数据

[
  {
    "itemid": "bf47",
    "name": "test",
    "workers": [
      {
        "user": {
          "id": "7074",
          "login": "john"
        },
        "status": [
          {
            "name": "WORK"
          }
        ]
      },
      
      {
        "user": {
          "id": "1237",
          "login": "peter"
        },
        "status": [
          {
            "name": "WORK"
          },
          {
            "name": "SLEEP"
          }
        ]
      }
    ]
  },
  {
    "itemid": "ea277",
    "name": "test",
    "workers": [
      {
        "user": {
          "id": "2ce0",
          "login": "robert"
        },
        "status": [
          {
            "name": "WORK"
          }
        ]
      }
    ]
  }
]

尝试的Java代码

String id =  Arrays.stream(allItemId).flatMap(x->x.getworkers().stream())
                .filter(x->x.getUser().getLogin().equals(peter))
                .flatMap(x->x.getStatus().stream())
                .filter(x->x.getName().equals("SLEEP")).map(x->x.getItemId).findFirst().get();

问题分析与解决方法

原代码问题

  1. 丢失原Item引用:使用flatMap展开workers后,后续操作对象变为Worker;再展开status后对象变为Status,此时x.getItemId完全无效——Status类不存在该方法。
  2. 筛选逻辑顺序错误:应该先对每个Item判断是否存在符合条件的Worker,而非直接展开所有Worker和Status,导致无法关联回原Item的itemid。

正确实现代码

假设POJO类分别为Item、Worker、User、Status,且所有字段的getter方法定义正确:

// 用Optional安全处理无匹配结果的情况
Optional<String> targetItemId = Arrays.stream(allItemId)
    .filter(item -> 
        // 检查当前Item的workers中是否存在符合条件的worker
        item.getWorkers().stream().anyMatch(worker -> 
            // worker的login是peter
            "peter".equals(worker.getUser().getLogin()) 
            // 且该worker包含status为SLEEP的状态
            && worker.getStatus().stream().anyMatch(status -> "SLEEP".equals(status.getName()))
        )
    )
    // 提取符合条件的Item的itemid
    .map(Item::getItemid)
    // 获取第一个匹配结果(若存在)
    .findFirst();

// 安全获取结果,避免无匹配时抛出NoSuchElementException
String id = targetItemId.orElse(null); 
// 也可根据业务需求处理空值,比如抛出自定义异常:
// String id = targetItemId.orElseThrow(() -> new IllegalArgumentException("未找到符合条件的itemid"));

代码逻辑说明

  1. 遍历所有Item对象,先对每个Item做筛选:
    • 检查该Item的workers列表中,是否存在login为peter的Worker
    • 同时该Worker的status列表中,是否包含name为SLEEP的状态
  2. 找到第一个符合条件的Item后,提取它的itemid
  3. 使用Optional包装结果,避免直接调用get()在无匹配时抛出异常,保证代码健壮性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 08:55:55