如何使用Java 8 Stream解析复杂嵌套对象并提取逗号分隔的目标值
问题背景
现有如下JSON结构,需要解析后返回逗号分隔的取值结果:
{ "globalCode": "12", "fields": [ { "localCode": "72879", "fieldValues": [ { "value": null, "subFields": [ { "localCode": "980", "subFieldValues": [ { "value": "lon" } ] }, { "localCode": "98", "subFieldValues": [ { "value": "KPO" } ] } ] } ] } ] }
需求说明
需要基于Java 8 Stream实现解析逻辑,最终返回字符串"lon,KPO"。现有迭代实现的else分支不知道如何用Stream改写,原有代码如下(注:原代码存在笔误,values.getSubFields()应为fieldValue.getSubFields()):
public String getValue(){ StringBuffer buffer = new StringBuffer(); List<Field> fields = //get fields for globalCode 72879 // line 2 for(Field field : fields){ List<FieldValue> fieldValues = field.getFieldValues(); for(FieldValue fieldValue : fieldValues) { if(fieldValue.getValue() != null){ buffer.append(fieldValue.getValue()); buffer.append(","); } else{ List<SubField> subFields = fieldValue.getSubFields(); for(SubField subField: subFields ){ List<SubFieldValue> subFieldValues = subField.getSubFieldValues(); for(SubFieldValue subFieldValue : subFieldValues ){ buffer.append(subFieldValue.getValue()); buffer.append(","); } } } } } return buffer.toString(); }
Stream改写实现
核心思路是通过flatMap逐层扁平化嵌套集合,同时处理value为空时的分支逻辑,最后直接通过Collectors.joining完成逗号拼接,还能避免原有代码末尾多逗号的问题:
import java.util.stream.Collectors; import java.util.stream.Stream; public String getValue(){ List<Field> fields = //get fields for globalCode 72879 // line 2 return fields.stream() // 展开所有Field的fieldValues .flatMap(field -> field.getFieldValues().stream()) // 对每个fieldValue拆分处理 .flatMap(fieldValue -> { if (fieldValue.getValue() != null) { // value非空直接返回当前值的单元素流 return Stream.of(String.valueOf(fieldValue.getValue())); } else { // value为空则逐层展开subFields和subFieldValues取value return fieldValue.getSubFields().stream() .flatMap(subField -> subField.getSubFieldValues().stream()) .map(subFieldValue -> String.valueOf(subFieldValue.getValue())); } }) // 用逗号拼接所有值,自动处理首尾无多余逗号 .collect(Collectors.joining(",")); }
如果要简化if分支,也可以用三元表达式改写:
.flatMap(fieldValue -> fieldValue.getValue() != null ? Stream.of(String.valueOf(fieldValue.getValue())) : fieldValue.getSubFields().stream() .flatMap(subField -> subField.getSubFieldValues().stream()) .map(subFieldValue -> String.valueOf(subFieldValue.getValue())) )
内容的提问来源于stack exchange,提问作者sammy
相关产品推荐
相关产品推荐

