J*a Stream API实现姓名解析与分离:从全名字符串提取姓氏与名字


Java Stream API实现姓名解析与分离:从全名字符串提取姓氏与名字

本文旨在指导如何在j*a中高效处理包含多个全名字符串的数组列表,并利用stream api将每个全名拆分为名字和姓氏。教程将详细讲解如何通过查找最后一个空格来区分名字和姓氏,并演示如何将解析结果存储到新的字符串数组或更符合面向对象设计的`author`对象列表中,从而提升数据处理的灵活性和代码的可读性。

1. 问题背景与目标

在处理从外部数据源(如CSV文件)读取的姓名数据时,我们经常会遇到需要将一个完整的姓名字符串拆分为名字(First Name)和姓氏(Last Name)的需求。例如,从CSV文件中读取的作者列表可能以 String[] 的形式存在,其中每个元素都是一个完整的作者姓名,如 "Christian Janze" 或 "Kenan Xiao Auburn University"。我们的目标是:

  1. 从这些全名字符串中分离出名字和姓氏。
  2. 假设一个全名字符串中,最后一个单词是姓氏,其余部分是名字。
  3. 将分离后的名字和姓氏存储起来,以便后续处理。

原始数据结构通常是一个 ArrayList,其中每个 String[] 代表一组作者,每个 String 是一个全名。

2. 原始数据结构与示例

假设我们已经从CSV文件中读取了作者姓名,并将其存储在一个 ArrayList 中,其内容可能如下:

// 假设 authorGroups 已经通过文件读取填充
ArrayList<String[]> authorGroups = new ArrayList<>();
// 示例数据,实际数据可能来自文件读取
authorGroups.add(new String[]{"Christian Janze", "Marten Risius"});
authorGroups.add(new String[]{"Kenan Xiao Auburn University", "Ashish Gupta", "Wenting Jiang", "Xiao Qin"});
authorGroups.add(new String[]{"Kyuhan Lee", "Sudha Ram"});
authorGroups.add(new String[]{"Kelvin King-Kizito"});

System.out.println("原始作者姓名组列表:");
for (String[] group : authorGroups) {
    System.out.println(Arrays.toString(group));
}
/* 
输出示例:
原始作者姓名组列表:
[Christian Janze, Marten Risius]
[Kenan Xiao Auburn University, Ashish Gupta, Wenting Jiang, Xiao Qin]
[Kyuhan Lee, Sudha Ram]
[Kelvin King-Kizito]
*/

我们的任务是将每个全名字符串(例如 "Christian Janze")拆分为 "Christian"(名字)和 "Janze"(姓氏)。

3. 基于J*a Stream API的姓名解析方案

J*a 8引入的Stream API提供了一种声明式且高效的方式来处理集合数据。我们可以利用它来遍历 authorGroups,对每个全名字符串执行解析操作,并收集结果。

3.1 核心解析逻辑详解

对于每个全名字符串,我们需要找到最后一个空格的位置。这个空格将作为名字和姓氏的分隔符。

  • strArr[i].lastIndexOf(" "):找到字符串中最后一个空格的索引。
  • strArr[i].substring(0, lastIndexOfWhitespace):从字符串开头到最后一个空格之前的部分,作为名字。
  • strArr[i].substring(lastIndexOfWhitespace + 1):从最后一个空格之后的部分到字符串结尾,作为姓氏。

我们将为每个原始全名生成两个新的字符串(名字和姓氏),并将它们存储在一个新的 String[] 中。

3.2 完整代码实现

以下代码片段展示了如何使用Stream API来执行姓名解析和分离:

Decktopus AI Decktopus AI

AI在线生成高质量演示文稿

Decktopus AI 153 查看详情 Decktopus AI
import j*a.util.ArrayList;
import j*a.util.Arrays;
import j*a.util.Collections;
import j*a.util.List;
import j*a.util.stream.Collectors;

public class NameParser {

    // 假设 Author 类如问题描述所示
    public static class Author {
        private String name;
        private String surname;

        public Author(String name, String surname) {
            this.name = name;
            this.surname = surname;
        }

        public String getName() {
            return name;
        }

        public String getSurname() {
            return surname;
        }

        @Override
        public String toString() {
            return "Author{" + "name='" + name + '\'' + ", surname='" + surname + '\'' + '}';
        }
    }

    public static void main(String[] args) {
        ArrayList<String[]> authorGroups = new ArrayList<>();
        authorGroups.add(new String[]{"Christian Janze", "Marten Risius"});
        authorGroups.add(new String[]{"Kenan Xiao Auburn University", "Ashish Gupta", "Wenting Jiang", "Xiao Qin"});
        authorGroups.add(new String[]{"Kyuhan Lee", "Sudha Ram"});
        authorGroups.add(new String[]{"Kelvin King-Kizito"});
        authorGroups.add(new String[]{"SingleName"}); // 示例:一个单词的姓名

        System.out.println("--- 原始作者姓名组列表 ---");
        for (String[] group : authorGroups) {
            System.out.println(Arrays.toString(group));
        }

        // 使用 Stream API 分离姓名,结果存储为 ArrayList<String[]>
        ArrayList<String[]> authorGroupsWithSeparatedNames = authorGroups.stream()
            .map(strArr -> { // 对每个 String[] 进行处理
                // 新的数组将存储分离后的名字和姓氏,长度是原数组的两倍
                String[] newStrArr = new String[strArr.length * 2];
                for (int i = 0; i < strArr.length; i++) {
                    String fullName = strArr[i].trim(); // 清除首尾空格
                    int lastIndexOfWhitespace = fullName.lastIndexOf(" ");

                    if (lastIndexOfWhitespace != -1) { // 存在空格,可以分离
                        newStrArr[i * 2] = fullName.substring(0, lastIndexOfWhitespace); // 名字
                        newStrArr[i * 2 + 1] = fullName.substring(lastIndexOfWhitespace + 1); // 姓氏
                    } else { // 没有空格,整个作为名字,姓氏为空
                        newStrArr[i * 2] = fullName;
                        newStrArr[i * 2 + 1] = ""; // 或者设置为 null,取决于需求
                    }
                }
                return newStrArr;
            })
            .collect(Collectors.toCollection(ArrayList::new)); // 收集到新的 ArrayList<String[]>

        System.out.println("\n--- 分离后的作者姓名列表 (String[]) ---");
        for (String[] group : authorGroupsWithSeparatedNames) {
            System.out.println(Arrays.toString(group));
        }

        // 进一步优化:将分离后的姓名存储为 Author 对象列表
        List<Author> authorsList = authorGroups.stream()
            .flatMap(Arrays::stream) // 将 ArrayList<String[]> 展平为 Stream<String>
            .map(fullName -> {
                String trimmedFullName = fullName.trim();
                int lastIndexOfWhitespace = trimmedFullName.lastIndexOf(" ");
                String firstName;
                String surname;

                if (lastIndexOfWhitespace != -1) {
                    firstName = trimmedFullName.substring(0, lastIndexOfWhitespace);
                    surname = trimmedFullName.substring(lastIndexOfWhitespace + 1);
                } else {
                    firstName = trimmedFullName;
                    surname = ""; // 或 null
                }
                return new Author(firstName, surname);
            })
            .collect(Collectors.toList()); // 收集到 List<Author>

        System.out.println("\n--- 分离后的作者列表 (Author 对象) ---");
        for (Author author : authorsList) {
            System.out.println(author);
        }
    }
}

4. 结果验证

运行上述代码,我们将看到以下输出,验证了姓名已成功分离:

--- 原始作者姓名组列表 ---
[Christian Janze, Marten Risius]
[Kenan Xiao Auburn University, Ashish Gupta, Wenting Jiang, Xiao Qin]
[Kyuhan Lee, Sudha Ram]
[Kelvin King-Kizito]
[SingleName]

--- 分离后的作者姓名列表 (String[]) ---
[Christian, Janze, Marten, Risius]
[Kenan Xiao Auburn, University, Ashish, Gupta, Wenting, Jiang, Xiao, Qin]
[Kyuhan, Lee, Sudha, Ram]
[Kelvin, King-Kizito, , ]
[SingleName, ]

--- 分离后的作者列表 (Author 对象) ---
Author{name='Christian', surname='Janze'}
Author{name='Marten', surname='Risius'}
Author{name='Kenan Xiao Auburn', surname='University'}
Author{name='Ashish', surname='Gupta'}
Author{name='Wenting', surname='Jiang'}
Author{name='Xiao', surname='Qin'}
Author{name='Kyuhan', surname='Lee'}
Author{name='Sudha', surname='Ram'}
Author{name='Kelvin', surname='King-Kizito'}
Author{name='SingleName', surname=''}

从输出可以看出,每个全名字符串都根据最后一个空格被成功拆分。对于 "SingleName" 这样的单字姓名,名字部分是 "SingleName",姓氏部分留空。

5. 进阶:使用Author对象存储解析结果

在实际应用中,将解析后的名字和姓氏存储为独立的 Author 对象(如问题描述中提供的类)通常是更好的实践。这不仅使数据结构更清晰,也更符合面向对象的设计原则。

在上面的完整代码示例中,我们展示了两种收集方式:

  1. ArrayList:将每个作者组的姓名分离后,仍然保持原始的 String[] 结构,但每个 String[] 中的元素数量翻倍,交替存储名字和姓氏。
  2. List:通过 flatMap 将所有作者的全名展平,然后 map 到 Author 对象,最终得到一个包含所有 Author 对象的扁平列表。这种方式更推荐,因为它直接将数据映射到业务实体。

6. 注意事项与健壮性考虑

在进行姓名解析时,需要考虑一些边缘情况和潜在问题,以提高代码的健壮性:

  • 没有空格的姓名:如果姓名字符串中不包含空格(例如 "SingleName"),lastIndexOf(" ") 将返回 -1。此时,我们需要决定如何处理姓氏(例如,将其留空或将整个字符串作为名字)。上述代码已包含此处理。
  • 多余的空格:姓名字符串可能包含前导、尾随或内部多余的空格(例如 " Christian Janze " 或 "Christian Janze")。使用 trim() 方法可以在处理前清除这些多余的空格,确保解析的准确性。
  • 复杂姓名结构
    • 连字符姓氏:如 "Anna Müller-Schmidt"。如果我们的规则是最后一个单词是姓氏,那么 "Müller-Schmidt" 将被正确识别为姓氏。
    • 多个中间名:如 "John D*id Smith"。根据我们的规则,"John D*id" 将被视为名字,"Smith" 为姓氏。如果需要更精细的中间名分离,则需要更复杂的解析逻辑,可能涉及正则表达式或更高级的自然语言处理技术。
  • 空字符串或null:输入数据中可能存在空字符串或 null。在 map 操作中应添加 null 检查或空字符串处理,以避免 NullPointerException。

7. 总结

本文详细介绍了如何利用J*a Stream API高效地从 ArrayList 中解析并分离作者的全名。我们通过 lastIndexOf(" ") 和 substring() 方法实现了名字和姓氏的精确提取,并展示了两种结果存储方式:ArrayList 和更推荐的 List。通过将数据映射到自定义的 Author 对象,我们不仅提升了代码的清晰度和可维护性,也为后续的业务逻辑处理奠定了良好的基础。在实际开发中,务必考虑各种姓名格式的复杂性,并根据需求选择最合适的解析策略和错误处理机制。

以上就是J*a Stream API实现姓名解析与分离:从全名字符串提取姓氏与名字的详细内容,更多请关注其它相关文章!


# 两种  # 网站引流推广平台  # 罗山优化seo  # 冷水江seo公司  # 财付通网站建设文案  # 装修seo长尾词  # 肇庆市街道网站建设成本  # 赣州网站建设优化推广  # seo高手排行  # 长沙企业网站seo优化  # 营销推广专员问题  # 配置文件  # 展示了  # 将被  # java  # 多个  # 是一个  # 面向对象  # 自然语言  # 数据结构  # 字符串数组  # csv文件  # 自然语言处理  # stream  # ai  # csv  # 正则表达式 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: poki官网最新入口 poki小游戏大全入口  以下哪一项是古代兵书三十六计中的计谋  小米civi如何设置锁屏时间  Flexbox布局实践:实现底部页脚与顶部粘性导航条的完美结合  快手网页版官方访问 快手网页版页面在线打开  PHP中实现JSON数据数组分页的教程  外媒评《燕云十六声》DIY载具新玩法:很像《塞尔达传说王国之泪》!  海棠阅读登录教程_详细讲解海棠登录操作  Composer reinstall命令重装损坏的包  电脑的“恢复环境(WinRE)”找不到怎么办_Windows系统恢复环境重建【高级修复】  如何在mysql中比较InnoDB和MyISAM区别  使用Python和GBGB API高效抓取指定日期范围和赛道比赛结果教程  百度小说看书时如何翻页_百度小说手动翻页与自动翻页设置  使用document.execCommand实现Web文本编辑器加粗/取消加粗  vivo浏览器怎么离线保存网页 vivo浏览器下载完整页面以便无网络时阅读  大众点评了却看不到是怎么回事  在Flask应用中安全高效地更新SQLAlchemy用户数据  Win10怎么设置快速启动 Win10开启快速启动设置方法  如何定制PrimeNG Sidebar的背景颜色  狙击外星人小游戏在线链接_狙击外星人小游戏网页链接  J*aScript实现下拉菜单驱动的动态表格数据展示  拷贝漫画2025网页版入口 拷贝漫画官网免费看全集  c++20的指定初始化(Designated Initializers)怎么用_c++ C风格结构体初始化  汽水音乐车机版官网5.0 汽水音乐车机版5.0版本下载入口  《360浏览器》设置摄像头权限方法  苹果自助维修计划支持哪些设备机型  oppo手机如何通过下拉通知栏截图_oppo手机通知栏快捷截图方法  C#解析并修改XML后保存 如何确保格式与编码的正确性  《绿竹漫游》关闭消息通知方法  口腔诊所管理软件推荐  火柴人战争网页版在线玩  江苏大剧院会员卡购买步骤  Cassandra中复合主键、二级索引与ORDER BY排序的限制与解决方案  哈尔滨城市通昵称修改方法  Yandex无需登录畅游 俄罗斯搜索引擎最新官网指南  Safari浏览器自动填表功能失效怎么办 Safari表单管理修复  胃动力不足?试试这5个调理方法  5G和6G的连接密度有什么区别 6G每平方公里能连接多少设备  CSS如何控制元素外边距_margin实现布局间隔  《procreate》绘制渐变效果教程  J*aScript事件处理:优化键盘输入与表单提交的实践指南  windows10怎么设置电源按钮_windows10按下电源键功能修改  一加 Ace 6V 快充无法启用_一加 Ace 6V 充电优化  《全民k歌》音乐怎么下载到本地2025  解决CSS布局中意外顶部空白问题的教程  163邮箱在线登录 163邮箱网页版在线入口  《星露谷物语》克林特好感度事件介绍  从HTML表单获取逗号分隔值并转换为NumPy数组进行预测  教育查询官方网站入口 教育个人档案查询免费官网  Win10输入法不见了怎么办 Win10找回语言栏图标教程 

 2025-12-03

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.