如何用Java 8 Stream将Trip列表转为Map<String, List<Trip>>?
问题解决:将Trip列表按员工empId分组为Map<String, List>
你之前的代码存在两个核心问题:
groupingBy的分类函数返回的是Stream<String>,导致Map的键类型为Stream而非目标String- 单个Trip包含多个员工,直接分组会把整个Trip绑定到员工ID的流上,无法实现「每个员工ID对应其参与的所有Trip」的需求
正确实现代码
通过flatMap先将每个Trip拆分为「员工ID - Trip」的对应关系,再按员工ID分组:
public static void main(String[] args) { List<Trip> trips = new ArrayList<>(); // 可添加测试数据示例: // trips.add(new Trip(new Date(), new Date(), Arrays.asList(new Employee("张三", "001"), new Employee("李四", "002")))); // trips.add(new Trip(new Date(), new Date(), Arrays.asList(new Employee("张三", "001")))); Map<String, List<Trip>> empIdToTrips = trips.stream() // 把每个Trip拆分为多个(empId, Trip)键值对 .flatMap(trip -> trip.getEmpList().stream() .map(emp -> new AbstractMap.SimpleEntry<>(emp.getEmpId(), trip))) // 按empId分组,收集对应Trip列表 .collect(Collectors.groupingBy( AbstractMap.SimpleEntry::getKey, Collectors.mapping(AbstractMap.SimpleEntry::getValue, Collectors.toList()) )); }
简化写法(利用Java 9+的Map.entry)
Map<String, List<Trip>> empIdToTrips = trips.stream() .flatMap(trip -> trip.getEmpList().stream() .map(emp -> Map.entry(emp.getEmpId(), trip))) .collect(Collectors.toMap( Map.Entry::getKey, e -> new ArrayList<>(Collections.singletonList(e.getValue())), (existingList, newTrips) -> { existingList.addAll(newTrips); return existingList; } ));
逻辑说明
flatMap负责将单个Trip展开为多个流元素,每个元素对应一个参与员工和当前Trip的绑定关系- 后续通过分组收集器,将同一员工ID对应的所有Trip聚合到列表中
内容的提问来源于stack exchange,提问作者Jha
相关产品推荐
相关产品推荐

