如何使用Java Stream API实现Codingbat的mirrorEnds题目
问题说明
给定来自CodingBat的mirrorEnds题目:
给定一个字符串,查找字符串首尾存在的镜像(逆序)子串。
即从字符串最开头取0个或多个字符,与字符串最末尾逆序排列的对应字符匹配(允许重叠)。例如字符串
"abXYZba"的镜像首尾结果为"ab"。
示例:
mirrorEnds("abXYZba") → "ab" mirrorEnds("abca") → "a" mirrorEnds("aba") → "aba"
现有命令式实现代码如下:
public String mirrorEnds(String str) { String result = ""; if (str.length() % 2 != 0) { for (int i = 0; i < str.length() / 2; i++) { if (str.charAt(i) == str.charAt(str.length() - i - 1)) { result += "" + str.charAt(i); } else { break; } } if (result.length() == str.length() / 2) { String strEnd = new StringBuilder(result).reverse().toString(); result += "" + str.charAt(str.length() / 2) + strEnd; } } if (str.length() % 2 == 0) { for (int i = 0; i < str.length() / 2; i++) { if (str.charAt(i) == str.charAt(str.length() - i - 1)) { result += "" + str.charAt(i); } else { break; } } if (result.length() == str.length() / 2) { String strEnd = new StringBuilder(result).reverse().toString(); result += strEnd; } } return result; }
核心疑问:是否可以使用Stream API实现该题目的功能?
解答
可以实现。这道题的核心逻辑是从字符串首尾两端开始逐位比对,遇到第一组不匹配的字符就立刻终止,用Stream的takeWhile方法刚好可以实现这个截断逻辑,而且不需要像原有实现那样单独判断字符串长度奇偶,代码更精简:
public String mirrorEnds(String str) { int matchLength = (int) IntStream.range(0, str.length()) .takeWhile(idx -> str.charAt(idx) == str.charAt(str.length() - 1 - idx)) .count(); return str.substring(0, matchLength); }
逻辑说明
- 用
IntStream.range生成从0开始递增的索引序列,takeWhile会持续判断当前索引位置的首尾字符是否相等,一旦遇到不相等的情况就立刻终止流遍历,完全匹配题目要求的匹配规则。 - 统计得到匹配长度后,直接从字符串头部截取对应长度的子串即可,不需要手动拼接前缀、中间字符、反转后缀:
- 对于
abXYZba,匹配到索引0、1,长度为2,截取结果为ab - 对于
abca,仅匹配到索引0,长度为1,截取结果为a - 对于
aba,三个索引位置全部匹配,长度为3,截取结果为完整串aba
- 对于
- 空串、单字符串等边界场景也可以自动兼容,不需要额外判断。
内容的提问来源于stack exchange,提问作者Evgeniy
相关产品推荐
相关产品推荐

