如何在Kotlin中基于detail字段对funName数组做分组转换?
Kotlin/Java实现按detail字段分组转换数据结构
原始数据结构
[ { "name": "a", "detail": [ "1", "2", "3" ] }, { "name": "b", "detail": [ "2", "3", "4" ] } ]
目标转换结构
[ { "detail": "1", "name": [ "a" ] }, { "detail": "2", "name": [ "a", "b" ] }, { "detail": "3", "name": [ "a", "b" ] }, { "detail": "4", "name": [ "b" ] } ]
优化后的原始数据类
你当前用Array<String>存储detail,由于Kotlin中Array的equals是引用比较,分组时容易出问题,建议换成List<String>:
data class FunName( @field:JsonProperty("name") val name: String = "", @field:JsonProperty("detail") val detail: List<String> = emptyList(), )
Kotlin实现方案
你初始尝试的groupBy { x -> x.detail }是把整个数组作为分组key,不符合需求。正确思路是先拆分每个detail元素与对应name,再按detail元素分组:
val data: Array<FunName> = ... // 你的原始数据 // 1. 定义目标结构的数据类(可选,也可以直接用Map) data class GroupedDetail( val detail: String, val name: List<String> ) // 2. 执行转换 val result: List<GroupedDetail> = data // 将每个FunName拆分为(detail元素, name)的配对 .flatMap { funName -> funName.detail.map { detailItem -> detailItem to funName.name } } // 按detail元素分组,收集对应的name列表 .groupBy( keySelector = { it.first }, valueTransform = { it.second } ) // 转换为目标结构 .map { (detail, names) -> GroupedDetail(detail, names) }
代码说明
- flatMap:把每个FunName的多个detail元素拆成独立条目,比如
FunName("a", listOf("1","2","3"))会被拆成("1","a")、("2","a")、("3","a")三个配对。 - groupBy:以detail元素为key,把所有关联的name收集成列表,得到
Map<String, List<String>>。 - map:把Map的键值对转换成你需要的目标结构。
Java实现方案
思路和Kotlin一致,利用Stream API完成拆分、分组、转换:
定义实体类
import com.fasterxml.jackson.annotation.JsonProperty; import java.util.List; public class FunName { @JsonProperty("name") private String name; @JsonProperty("detail") private List<String> detail; public FunName() {} public FunName(String name, List<String> detail) { this.name = name; this.detail = detail; } // getter和setter public String getName() { return name; } public void setName(String name) { this.name = name; } public List<String> getDetail() { return detail; } public void setDetail(List<String> detail) { this.detail = detail; } } public class GroupedDetail { private String detail; private List<String> name; public GroupedDetail(String detail, List<String> name) { this.detail = detail; this.name = name; } // getter和setter public String getDetail() { return detail; } public void setDetail(String detail) { this.detail = detail; } public List<String> getName() { return name; } public void setName(List<String> name) { this.name = name; } }
转换代码
import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class DataConverter { public static List<GroupedDetail> convert(FunName[] data) { return List.of(data) .stream() // 拆分detail元素与对应name .flatMap(funName -> funName.getDetail().stream() .map(detailItem -> Map.entry(detailItem, funName.getName())) ) // 按detail分组收集name .collect(Collectors.groupingBy( Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toList()) )) // 转换为目标结构 .entrySet() .stream() .map(entry -> new GroupedDetail(entry.getKey(), entry.getValue())) .collect(Collectors.toList()); } }
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

