Java8如何优化分隔字符串转Person对象列表、避免索引引用?
问题修复与Java8优化实现
原有代码存在隐藏bug:按照你给出的字符串规则,3属性块的结构为
name|id|accessCode,对应索引为0/1/2,原代码中withAccessCode(val[3])在处理3属性块时会直接抛出ArrayIndexOutOfBoundsException,同时optionalID的取值逻辑也错误取了val[3]而非val[2]。
我们可以用Java8 Stream + 迭代器按顺序取值的方式,完全避免硬编码数组索引,同时实现更函数式的无副作用写法:
public String getParsed(String str) throws JsonProcessingException { // 拆分原始字符串,过滤空块(避免末尾|||产生的空字符串) List<Person> personList = Pattern.compile("\\|\\|\\|") .splitAsStream(str) .filter(StringUtils::isNotBlank) // 拆分单person属性数组 .map(item -> item.split(Pattern.quote("|"))) // 校验属性长度符合要求(最少3个、最多4个) .filter(val -> val.length >= 3 && val.length <= 4) .map(valArr -> { // 用迭代器按顺序取值,完全消除硬编码索引 Iterator<String> attrIter = Arrays.asList(valArr).iterator(); return PersonBuilder.asPerson() .withName(attrIter.next()) .withId(attrIter.next()) .withAccessCode(attrIter.next()) .withOptionalId(attrIter.hasNext() ? attrIter.next() : StringUtils.EMPTY) .build(); }) .collect(Collectors.toList()); // 空集合按需求返回空串或序列化后的空数组均可 return CollectionUtils.isEmpty(personList) ? StringUtils.EMPTY : mapper.writeValueAsString(personList); }
核心优化点
- 完全消除硬编码数组索引,后续如果属性顺序调整,只需要调整迭代器取值的顺序即可,不会出现索引写错的问题
- 用
splitAsStream直接生成流,避免了中间数组的转换,写法更简洁 - 增加了属性长度校验,避免不符合规则的块进入后续逻辑
- 全程无副作用的函数式写法,不需要在流外部声明集合来接收结果,线程安全性更好
如果需要兼容单个属性为空的场景,可把attrIter.next()包一层Optional.ofNullable().orElse(StringUtils.EMPTY)即可。
内容的提问来源于stack exchange,提问作者Jeeppp
相关产品推荐
相关产品推荐

