Java字符串数字单词排序技巧
本文详细介绍了使用Java结合正则表达式和Stream API实现字符串单词数字排序的方法,旨在解决字符串乱序问题。通过巧妙运用正向先行和后行断言,将包含数字的字符串分割成“单词+数字”片段,并利用Map存储单词与数字的对应关系。文章重点讲解了如何利用`split()`方法和`Collectors.toMap()`函数,并强调了使用`TreeMap`保证排序的重要性,确保最终按数字顺序重组字符串。本文提供完整的示例代码,并针对代码可读性、维护性以及数字范围等问题提出了注意事项,助力开发者构建高效准确的字符串处理解决方案。

问题描述
在日常编程中,我们有时会遇到需要根据字符串中内嵌的数字来重新排列单词的需求。例如,给定字符串 "my1kiran4name2is3",其中每个单词后面都跟着一个数字(1-9),表示该单词在最终序列中的位置。我们的目标是根据这些数字,将单词重新排列为 "my name is kiran"。
示例:
- my 对应数字 1
- kiran 对应数字 4
- name 对应数字 2
- is 对应数字 3
按数字顺序排列后,结果应为:my (1) name (2) is (3) kiran (4)。
解决方案:基于正则表达式与 Stream API
解决此问题的一种高效方法是结合使用 Java 的正则表达式(特别是零宽断言)和 Stream API。这种方法能够优雅地将单词与数字分离,并进行后续处理。
核心思路
- 初始分割: 将整个字符串分割成“单词+数字”的片段(例如:"my1", "kiran4")。
- 二次分割与映射: 对每个片段,进一步将其分割为独立的单词和数字,并构建一个映射(Map),其中数字作为键,单词作为值。
- 排序与重组: 根据数字键的顺序,从映射中提取单词,并用空格连接起来形成最终的字符串。
步骤详解
我们将以字符串 "my1kiran4name2is3" 为例,逐步解释代码逻辑。
1. 初始分割:利用正向后行断言 ((?<=\\d))
第一步是将原始字符串根据数字进行分割,但要保留数字作为每个片段的结尾。这里使用正则表达式 (?<=\\d),它是一个正向后行断言(Positive Lookbehind)。这意味着它会匹配紧跟在一个数字 (\\d) 后面的位置,但不会将数字本身包含在匹配结果中。
String string = "my1kiran4name2is3";
// string.split("(?<=\\d)") 的结果是:["my1", "kiran4", "name2", "is3"]经过这一步,我们得到了一个包含“单词+数字”形式的字符串列表。
2. 二次分割与映射:利用正向先行断言 ((?=\\d)) 并构建 Map
接下来,对上一步得到的每个片段(如 "my1"),我们需要将其进一步分割成单词和数字。这里使用 s.split("(?=\\d)"),(?=\\d) 是一个正向先行断言(Positive Lookahead)。它会匹配紧跟在一个数字 (\\d) 前面的位置,但同样不将数字本身包含在匹配结果中。这使得数字成为分割后的第二个元素。
// 以 "my1" 为例,s.split("(?=\\d)") 的结果是:["my", "1"]
// 以 "kiran4" 为例,s.split("(?=\\d)") 的结果是:["kiran", "4"]然后,我们使用 Stream API 的 collect(Collectors.toMap(...)) 方法将这些分割后的数组转换为一个 Map
Map<Integer, String> map = Arrays.asList(string.split("(?<=\\d)")) // 将分割结果转换为 List
.stream() // 创建 Stream
.map(s -> s.split("(?=\\d)")) // 对每个元素进行二次分割
.collect(Collectors.toMap(e -> Integer.parseInt(e[1]), e -> e[0]));
// 最终得到的 map 可能是:{1="my", 4="kiran", 2="name", 3="is"}
// 注意:HashMap 的迭代顺序不确定,下文会详细说明。3. 重组字符串:连接 Map 中的值
最后一步是从 map 中提取单词并用空格连接。原始解决方案直接使用了 map.values().stream().collect(Collectors.joining(" "))。
string = map.values().stream()
.collect((Collectors.joining(" ")));
// 假设 map.values() 按键的顺序迭代,则结果为 "my name is kiran"完整示例代码
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.TreeMap; // 导入 TreeMap 以确保排序
public class StringSorter {
public static void main(String[] args) {
String inputString = "my1kiran4name2is3";
System.out.println("原始字符串: " + inputString);
// 步骤1 & 2: 分割并构建 Map
Map<Integer, String> wordMap =
Arrays.asList(inputString
.split("(?<=\\d)")) // 第一次分割:["my1", "kiran4", "name2", "is3"]
.stream()
.map(s -> s.split("(?=\\d)")) // 第二次分割:[["my", "1"], ["kiran", "4"], ...]
// 使用 TreeMap::new 确保 Map 内部按键排序
.collect(Collectors.toMap(
e -> Integer.parseInt(e[1]), // 键:数字
e -> e[0], // 值:单词
(oldValue, newValue) -> oldValue, // 处理重复键(此处不应发生)
TreeMap::new // 指定使用 TreeMap
));
// 步骤3: 从 Map 中按键顺序提取值并连接
String sortedString = wordMap
.values() // TreeMap 的 values() 方法会按键的自然顺序迭代
.stream()
.collect(Collectors.joining(" "));
System.out.println("排序后的字符串: " + sortedString);
}
}输出:
原始字符串: my1kiran4name2is3 排序后的字符串: my name is kiran
注意事项
代码可读性与维护性: 虽然上述解决方案利用了正则表达式和 Stream API 的强大功能,但其简洁性有时会牺牲一定的可读性,特别是对于不熟悉正则表达式零宽断言的开发者。在实际项目中,如果团队成员对这些高级特性不熟悉,可能需要添加详细注释或考虑更直观(尽管可能更冗长)的实现方式。
Map 的排序问题: 原始的 Collectors.toMap 默认创建的是 HashMap。HashMap 不保证元素的迭代顺序,这意味着 map.values().stream() 所产生的单词顺序可能不是按数字从小到大排列的。为了确保最终输出的单词严格按照数字顺序排列,应采取以下两种策略之一:
- 指定使用 TreeMap: 在 collect 阶段指定使用 TreeMap,如示例代码所示。TreeMap 会自动根据键的自然顺序(对于 Integer 来说就是数值大小)进行排序。 collect(Collectors.toMap(keyMapper, valueMapper, mergeFunction, TreeMap::new))
- 对 Map.Entry 进行排序: 如果必须使用 HashMap 或其他不保证顺序的 Map 实现,可以在获取值之前对 Map.Entry 进行排序: map.entrySet().stream().sorted(Map.Entry.comparingByKey()).map(Map.Entry::getValue).collect(Collectors.joining(" ")); 本文提供的示例代码已采用第一种方法,通过指定 TreeMap::new 来保证最终输出的正确排序。
数字范围与格式: 本解决方案假设数字为单个数字(1-9)。如果字符串中的数字可能是多位数(例如 "word10"),则正则表达式 \\d 需要修改为 \\d+(匹配一个或多个数字),并且相应的 split 逻辑需要确保正确处理多位数字。例如,"word10" 使用 s.split("(?=\\d)") 仍会得到 ["word", "10"],所以对于多位数是兼容的。但如果数字前或后有其他字符,则需要更复杂的正则匹配。
总结
本教程详细展示了如何利用 Java 的正则表达式(特别是正向先行和后行断言)和 Stream API 来解决根据内嵌数字对字符串中单词进行排序的问题。通过将复杂的字符串处理分解为逻辑清晰的步骤:分割、映射和重组,并注意 Map 的排序特性,我们可以构建出既高效又准确的解决方案。在实际应用中,除了关注功能的实现,代码的可读性和健壮性(如处理不同数字范围和确保排序)同样至关重要。
以上就是《Java字符串数字单词排序技巧》的详细内容,更多关于的资料请关注golang学习网公众号!
豆包AI宠物训练工具,让宠物更听话秘诀
- 上一篇
- 豆包AI宠物训练工具,让宠物更听话秘诀
- 下一篇
- 36漫画书单创建与分享教程
-
- 文章 · java教程 | 5小时前 | interrupt() 优雅关闭 中断状态 Java线程中断 协作式中断
- Java线程安全中断与状态管理方法
- 161浏览 收藏
-
- 文章 · java教程 | 5小时前 |
- Java8方法引用教程与实例解析
- 258浏览 收藏
-
- 文章 · java教程 | 5小时前 |
- Java接口与实现分离方法解析
- 490浏览 收藏
-
- 文章 · java教程 | 5小时前 |
- H2与Oracle冲突解决全攻略
- 427浏览 收藏
-
- 文章 · java教程 | 5小时前 |
- Java转Map方法实用教程
- 394浏览 收藏
-
- 文章 · java教程 | 5小时前 |
- Java处理UnsupportedOperationException异常技巧
- 249浏览 收藏
-
- 文章 · java教程 | 6小时前 |
- Linux部署K8s和Java容器教程
- 269浏览 收藏
-
- 文章 · java教程 | 6小时前 |
- Java避免类重复的实用技巧
- 404浏览 收藏
-
- 文章 · java教程 | 6小时前 |
- Java并发synchronized线程安全详解
- 464浏览 收藏
-
- 文章 · java教程 | 6小时前 |
- List与Set区别详解及选择方法
- 492浏览 收藏
-
- 文章 · java教程 | 6小时前 |
- 递归归并排序与多路合并实践解析
- 244浏览 收藏
-
- 文章 · java教程 | 6小时前 |
- Maven依赖冲突解决与版本升级技巧
- 180浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3204次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3417次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3446次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4555次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 3824次使用
-
- 提升Java功能开发效率的有力工具:微服务架构
- 2023-10-06 501浏览
-
- 掌握Java海康SDK二次开发的必备技巧
- 2023-10-01 501浏览
-
- 如何使用java实现桶排序算法
- 2023-10-03 501浏览
-
- Java开发实战经验:如何优化开发逻辑
- 2023-10-31 501浏览
-
- 如何使用Java中的Math.max()方法比较两个数的大小?
- 2023-11-18 501浏览

