首页 > 技术文章 > StringJoiner

wansw 2019-01-05 20:05 原文

示例一

public class StringJoinerTest1 {
    public static void main(String[] args) {
        StringJoiner joiner = new StringJoiner("--", "[[[_ ", "_]]]");
        System.out.println(joiner.toString());
        System.out.println(joiner.length());
    }
}
// result
[[[_ _]]]
8

API介绍

StringJoiner 是 java8 新增的类。

构造器:

public StringJoiner(CharSequence delimiter,
                        CharSequence prefix,
                        CharSequence suffix) {
        Objects.requireNonNull(prefix, "The prefix must not be null");
        Objects.requireNonNull(delimiter, "The delimiter must not be null");
        Objects.requireNonNull(suffix, "The suffix must not be null");
        // make defensive copies of arguments
        this.prefix = prefix.toString();
        this.delimiter = delimiter.toString();
        this.suffix = suffix.toString();
        this.emptyValue = this.prefix + this.suffix;
}

public StringJoiner(CharSequence delimiter) {
        this(delimiter, "", "");
}

delimiter 是分隔符 , prefix 是前缀 , suffix 是 后缀.

emptyValue 是本类的空值.

add

StringJoiner joiner = new StringJoiner("--", "[[[_", "_]]]");
joiner.add("1");
System.out.println("toString: " + joiner.toString());
System.out.println("length: " + joiner.length());

分析源码:

public StringJoiner add(CharSequence newElement) {
		prepareBuilder().append(newElement);
		return this;
}
private StringBuilder prepareBuilder() {
		if (value != null) {
				value.append(delimiter);
		} else {
				value = new StringBuilder().append(prefix);
		}
		return value;
}
public AbstractStringBuilder append(CharSequence s) {
		if (s == null)  return appendNull();
		if (s instanceof String)  return this.append((String)s);
		if (s instanceof AbstractStringBuilder)
				return this.append((AbstractStringBuilder)s);
		return this.append(s, 0, s.length());
}

​ 发现StringJoiner底层依旧使用的 StringBuilder,第一次添加数据时,会生成StringBuilder对象,并添加 “前缀”,后续添加字符时,追加 “分隔符”,最后调用 append 方法,最底层调用 System.arraycopy 方法。

public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)

src:源数组

srcPos:源数组要复制的起始位置

dest:目的数组

destPos:目的数组放置的起始位置

length:复制的长度

注意:src and dest都必须是同类型或者可以进行转换类型的数组.

toString

public String toString() {
        if (value == null) {
            return emptyValue;
        } else {
            if (suffix.equals("")) {
                return value.toString();
            } else {
                int initialLength = value.length();
                String result = value.append(suffix).toString();
                value.setLength(initialLength);
                return result;
            }
        }
    }

value == null, 返回 空。

不为空,判断 是否需要添加 后缀

length

public int length() {
        // Remember that we never actually append the suffix unless we return
        // the full (present) value or some sub-string or length of it, so that
        // we can add on more if we need to.
        return (value != null ? value.length() + suffix.length() :
                emptyValue.length());
    }
}

value 不为 null ,返回 value的长度 + 后缀长度(不为null时,已经计算了value+前缀)

merge

StringJoiner joiner = new StringJoiner("--", "[[[_", "_]]]");
joiner.add("1").add("2").add("3").add("4");

StringJoiner joiner2 = new StringJoiner("...");
joiner2.add("a").add("b").add("c");

joiner.merge(joiner2);
System.out.println(joiner.toString());

分析:

public StringJoiner merge(StringJoiner other) {
		Objects.requireNonNull(other);
		if (other.value != null) {
				final int length = other.value.length();
        // lock the length so that we can seize the data to be appended
        // before initiate copying to avoid interference, especially when
        // merge 'this'
        StringBuilder builder = prepareBuilder();
				builder.append(other.value, other.prefix.length(), length);
		}
		return this;
}
// result
[[[_1--2--3--4--a...b...c_]]]

实例二

import java.util.StringJoiner;

public class StringJoinerTest {

    public static void main(String args[]) {

        StringJoiner joiner = new StringJoiner("--", "[[[_", "_]]]");
        System.out.println("toString: " + joiner.toString());
        System.out.println("length: " + joiner.length());

        System.out.println();

        joiner.add("1");
        joiner.add("2");
        joiner.add("3");
        joiner.add("4");
        System.out.println("toString: " + joiner.toString());
        System.out.println("length: " + joiner.length());

    }
}
// result
toString: [[[__]]]
length: 8

toString: [[[_1--2--3--4_]]]
length: 18

推荐阅读