如何用NativeQuery结果填充Map<Integer, ArrayList<String>>结构
解决方案
你当前的问题在于直接使用Collectors.toMap会因为重复的code键抛出异常,且未将同一code对应的多个email收集为列表。可以通过Collectors.groupingBy结合Collectors.mapping实现需求,具体代码如下:
@Override public Map<Integer, ArrayList<String>> returnCodeEmail() { String sql = "SELECT DISTINCT code, email FROM user"; return entityManager.createNativeQuery(sql) .getResultList() .stream() // nativeQuery默认返回Object[],每个元素对应查询的列 .collect(Collectors.groupingBy( row -> ((Number) row[0]).intValue(), // 将code转为Integer类型 Collectors.mapping( row -> (String) row[1], // 提取email字符串 Collectors.toCollection(ArrayList::new) // 收集为ArrayList ) )); }
关键说明:
Collectors.groupingBy:以code作为分组键,将相同code的行聚合到一起。Collectors.mapping:提取每行中的email字段并转换为String类型。Collectors.toCollection(ArrayList::new):指定收集结果为ArrayList,匹配你需要的ArrayList<String>类型。- 注意
nativeQuery默认返回Object[]数组而非Tuple,需通过数组下标获取对应列的值并完成类型转换。
如果你的JPA版本支持,也可以指定返回类型为Tuple,通过字段名取值更清晰:
@Override public Map<Integer, ArrayList<String>> returnCodeEmail() { String sql = "SELECT DISTINCT code, email FROM user"; return entityManager.createNativeQuery(sql, Tuple.class) .getResultList() .stream() .collect(Collectors.groupingBy( tuple -> ((Number) tuple.get("code")).intValue(), Collectors.mapping( tuple -> tuple.get("email").toString(), Collectors.toCollection(ArrayList::new) ) )); }
内容的提问来源于stack exchange,提问作者Anck8
相关产品推荐
相关产品推荐

