JDK8字符串拼接的正确姿势

1. 对列表中的元素进行拼接

以前,对一个列表中的字符串进行拼接时,常见的代码如示例1所示:

代码示例1

        List<String> ids = ImmutableList.of("1", "2", "3");
        StringBuilder sb = new StringBuilder();
        for (String id : ids) {
            if (sb.length() > 0) {
                sb.append(",");
            }
            sb.append(id);
        }
        System.out.println(sb);

运行结果

1,2,3

示例1的代码没有问题,结果也是正确的,唯一的缺憾就是:代码比较长。

在JDK8之后,上述代码可以简化:

代码实例2

        List<String> ids = ImmutableList.of("1", "2", "3");
        System.out.println(String.join(",", ids));

运行结果

1,2,3

代码由原来的9行缩短到2行,非常简洁,最主要的是节省了时间(时间就是生命啊)。

JDK是如何实现的呢,源码如下:

    public static String join(CharSequence delimiter, Iterable<? extends CharSequence> elements) {
        Objects.requireNonNull(delimiter);
        Objects.requireNonNull(elements);
        StringJoiner joiner = new StringJoiner(delimiter);
        for (CharSequence cs: elements) {
            joiner.add(cs);
        }
        return joiner.toString();
    }

原来是使用了StringJoiner,StringJoiner是JDK8为了方便构造限定分隔符,甚至于给定前缀和后缀,而提供的一个类,示例代码如下:

        StringJoiner sj = new StringJoiner(",","{","}");
        sj.add("first").add("second").add("third");
        System.out.println(sj.toString());

运行结果

{first,second,third}

结合JDK8的stream,可以拼接列表元素:

        List<Integer> numbers = ImmutableList.of(1, 2, 3, 4, 5);
        System.out.println(numbers.stream().map(Object::toString).collect(Collectors.joining(",")));

运行结

1,2,3,4,5

2. 追加字符串

在开发的过程中,经常遇到将字符串追加到已有的字段中,例如:将用户的一些数据追加到一个字段中。当时看到这个需求后,凭借第一印象,立即写出了如下的代码:

代码实例3

        User user = new User();
        StringBuilder sb = new StringBuilder(user.getRemark());
        List<String> ids = ImmutableList.of("1", "2", "3");
        for (String id : ids) {
            if (sb.length() > 0) {
                sb.append(",");
            }
            sb.append(id);
        }
        user.setRemark(sb.toString());
        System.out.println(user);

运行,竟然报空指针异常,一口老血喷了出来。通过异常信息,结合StringBuilder源码:

    public StringBuilder(String str) {
        super(str.length() + 16);
        append(str);
    }

oh my god,在StringBuilder初始化时,为了初始化空间的大小,取了字符串的长度。然而,新用户的remark字段是空的,取其长度,字段就报错了。
结合前面学习的StringJoiner,新的代码如下:

        User user = new User();
        List<String> ids = ImmutableList.of("1", "2", "3");
        StringJoiner sj = new StringJoiner(",");
        if (StringUtils.isNoneEmpty(user.getRemark())) {
            sj.add(user.getRemark());
        }
        for (String id : ids) {
            sj.add(id);
        }
        System.out.println(sj.toString());

运行结果

1,2,3

当然,如果还想再短一点,可以将for循环简写:

        User user = new User();
        List<String> ids = ImmutableList.of("1", "2", "3");
        StringJoiner sj = new StringJoiner(",");
        if (StringUtils.isNoneEmpty(user.getRemark())) {
            sj.add(user.getRemark());
        }
        sj.add(String.join(",", ids));
        System.out.println(sj.toString());
posted @ 2019-03-22 21:27  Acode  阅读(17370)  评论(0编辑  收藏  举报
您是本站第访问量位访问者!