如何在Java中优雅实现非规范化数据到关系型结构的转换?
无需手动维护Map的优雅转换实现
针对将非规范化的Foo实体转换为Bar+Baz的关系型结构,有两种无需手动维护Map的优雅实现方式:
方式一:利用Stream API分组(推荐)
通过Java Stream的Collectors.groupingBy自动完成分组逻辑,无需手动处理Map的增删操作,代码简洁易读:
先定义实体类:
record Foo(int id, String discriminator, String value, String otherValue) {} record Baz(String value, String otherValue) {} record Bar(String discriminator, List<Baz> bazList) {}
转换代码:
List<Foo> fooList = // 你的Foo实例集合 List<Bar> barList = fooList.stream() // 按discriminator自动分组,内部封装了Map但无需手动维护 .collect(Collectors.groupingBy(Foo::discriminator)) .entrySet().stream() // 将分组结果映射为Bar对象 .map(entry -> new Bar( entry.getKey(), entry.getValue().stream() .map(foo -> new Baz(foo.value(), foo.otherValue())) .toList() )) .toList();
方式二:排序后遍历(无Map依赖)
如果可以先对Foo列表按discriminator排序,就能通过一次遍历完成转换,完全不依赖Map:
List<Foo> fooList = // 你的Foo实例集合 // 先按discriminator排序 List<Foo> sortedFooList = fooList.stream() .sorted(Comparator.comparing(Foo::discriminator)) .toList(); List<Bar> barList = new ArrayList<>(); if (sortedFooList.isEmpty()) { return barList; } // 初始化当前分组的标识和Baz列表 String currentDiscriminator = sortedFooList.get(0).discriminator(); List<Baz> currentBazList = new ArrayList<>(); for (Foo foo : sortedFooList) { if (foo.discriminator().equals(currentDiscriminator)) { // 同分组,添加Baz currentBazList.add(new Baz(foo.value(), foo.otherValue())); } else { // 切换分组,先把当前分组的Bar加入结果 barList.add(new Bar(currentDiscriminator, currentBazList)); // 更新分组标识和Baz列表 currentDiscriminator = foo.discriminator(); currentBazList = new ArrayList<>(); currentBazList.add(new Baz(foo.value(), foo.otherValue())); } } // 添加最后一个分组的Bar barList.add(new Bar(currentDiscriminator, currentBazList));
两种方式各有适用场景:Stream分组方式更简洁,适合大多数情况;排序遍历方式完全无Map依赖,适合对性能有极致要求或数据本身已排序的场景。
内容的提问来源于stack exchange,提问作者JohnnyBravo442
相关产品推荐
相关产品推荐

