Java Split Util

Last Modified: 2023/11/18

概述

本文分享一个分割字符串的方法,该方法会让你更安全的使用 split 的结果,让你远离 IndexOutOfIndexException。

Java Split 方法的困扰

在使用 Java 的 split 方法分割字符串时往往需要判断分割后数组的长度,这源于两方面原因:

  • 一、数据本身可能并不是完全格式化的,如果待处理的数据包含的分隔符个数不同,那么分割后的数组长度自然不同;
  • 二、分隔符的个数并不能决定分割后数组的长度。假设我们想按照逗号分割字符串 “a,b,c,,,” ,分割后的数组长度实际上为 3,而不是 6。

不论哪种情况,当我们想将分割后的结果赋值给其他变量的时候不得不小心地检查下标是否越界,否则等待你的将会是 IndexOutOfBoundException。

假设有一个待处理的文本文件,文件的每一行记录了一个用户信息,包含用户的姓名、年龄、Email 和联系方式,其中 Email 和联系方式是可选的。

MusicLover,18
StarGazer,20,stargazer@gmail.com
TechMaster,20,techmaster@gmail.com,18536428596

我们决定定义一个 splitLine 函数,由该函数负责解析数据行并返回一个解析后的 User 对象。

User splitLine(String line) {
    User user = new User();
    String[] splits = line.split(",");
    user.name = splits[0];
    user.age = splits[1];
    // index check
    if (splits.length > 2) {
        user.email = splits[2];
    }
    // index check
    if (splits.length > 3) {
        user.mobile = splits[3];
    }
    return user;
}

User 定义如下

public class User {
    public String name;
    public String age;
    public String email;
    public String mobile;
}

由于 split 之后数组的长度可能为 2 到 4,因此在取 email 和 mobile 的时候不得不进行下标校验。假如数组下标越界访问时不报错,而是返回 null,那么问题是不是就解决了呢?

当然这只是我们的假设,为了安全考虑,Java 是不会支持数组越界访问的。但是针对这个特定的问题,我们可以考虑封装一个 split 方法,该方法返回一个 SplitResult 对象,该对象的特性是支持任意下标的访问,只不过对那些越界下标的访问直接返回 null 而不是报错。

封装 Java Split 方法的返回结果

public class SplitResult {
    private final String[] splits;

    public SplitResult(String[] splits) {
        this.splits = splits;
    }

    public String get(int index) {
        return index >= this.splits.length ? null : this.splits[index];
    }
}

接下来就是 split 的具体实现

public static SplitResult split(String str, String delimiter) {
    String[] splits = str.split(delimiter);
    return new SplitResult(splits);
}

有了这个 split 之后,让我们重写一下上面的 splitLine 方法

User splitLine(String line) {
    User user = new User();
    SplitResult splits = split(line, ",");
    user.name = splits.get(0);
    user.age = splits.get(1);
    user.email = splits.get(2);
    user.mobile = splits.get(3);
    return user;
}

和之前的实现对比,代码简洁很多而且再也不用担心数组下标越界了。点击这里查看完整代码

有问题吗?点此反馈!

温馨提示:反馈需要登录