讲师中心 微信公众号
AI工具推荐 视频效率加速

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

阿宇小哥_9607

阿宇小哥_9607

发布时间:2025-12-03 18:59:09

|

530人浏览过

|

来源于php中文网

原创

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

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

1. 问题背景与目标

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

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

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

2. 原始数据结构与示例

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

// 假设 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"(姓氏)。

立即学习“Java免费学习笔记(深入)”;

3. 基于Java Stream API的姓名解析方案

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

3.1 核心解析逻辑详解

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

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

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

JavaStoryDevelop
JavaStoryDevelop

你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在

下载

3.2 完整代码实现

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

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.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[] 结构,但每个 String[] 中的元素数量翻倍,交替存储名字和姓氏。
  2. List<Author>:通过 flatMap 将所有作者的全名展平,然后 map 到 Author 对象,最终得到一个包含所有 Author 对象的扁平列表。这种方式更推荐,因为它直接将数据映射到业务实体。

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

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

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

7. 总结

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

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

PixTV
PixTV Hot

PixTV是一款面向AIGC内容创作的AI视频生成工具。

Laper
Laper Hot

Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

相关专题

更多
js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

4396

2023.06.20

正则表达式不包含
正则表达式不包含

正则表达式,又称规则表达式,,是一种文本模式,包括普通字符和特殊字符,是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串,通常被用来检索、替换那些符合某个模式的文本。php中文网给大家带来了有关正则表达式的相关教程以及文章,希望对大家能有所帮助。

2921

2023.07.05

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

8062

2023.07.05

java正则表达式匹配字符串
java正则表达式匹配字符串

在Java中,我们可以使用正则表达式来匹配字符串。本专题为大家带来java正则表达式匹配字符串的相关内容,帮助大家解决问题。

812

2023.08.11

正则表达式空格
正则表达式空格

正则表达式空格可以用“s”来表示,它是一个特殊的元字符,用于匹配任意空白字符,包括空格、制表符、换行符等。本专题为大家提供正则表达式相关的文章、下载、课程内容,供大家免费下载体验。

520

2023.08.31

Python爬虫获取数据的方法
Python爬虫获取数据的方法

Python爬虫可以通过请求库发送HTTP请求、解析库解析HTML、正则表达式提取数据,或使用数据抓取框架来获取数据。更多关于Python爬虫相关知识。详情阅读本专题下面的文章。php中文网欢迎大家前来学习。

673

2023.11.13

正则表达式空格如何表示
正则表达式空格如何表示

正则表达式空格可以用“s”来表示,它是一个特殊的元字符,用于匹配任意空白字符,包括空格、制表符、换行符等。想了解更多正则表达式空格怎么表示的内容,可以访问下面的文章。

386

2023.11.17

正则表达式中如何匹配数字
正则表达式中如何匹配数字

正则表达式中可以通过匹配单个数字、匹配多个数字、匹配固定长度的数字、匹配整数和小数、匹配负数和匹配科学计数法表示的数字的方法匹配数字。更多关于正则表达式的相关知识详情请看本专题下面的文章。php中文网欢迎大家前来学习。

719

2023.12.06

Playwright 测试失败怎么办
Playwright 测试失败怎么办

Playwright测试失败专题汇集超时、定位器匹配、浏览器提前关闭、依赖与插件配置、文件上传、SSL及Docker启动等故障文章,并介绍通过截图、报告和Trace定位错误。

20

2026.10.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn