前言
最近出于习惯问题,顺手点开了String的源码,意外发现String在JDK 8中新增了join方法。(实在惭愧,JDK 8都发布多久了。。。)
源码
String重载了join方法,两个方法的异同点在于,第一个方法使用的可变参数,第二个方法使用的可迭代参数,这样设计主要是为了方法适用性更广。比如参数可以传一个数组、集合等等。下面就拿一个方法的源码来解析
String 类
/** * delimiter 分隔符 * elements 需要连接的字符数组 */ public static String join(CharSequence delimiter, CharSequence... elements) { // 空指针判断 Objects.requireNonNull(delimiter); Objects.requireNonNull(elements); // Number of elements not likely worth Arrays.stream overhead. // 此处用到了StringJoiner(JDK 8引入的类) // 先构造一个以参数delimiter为分隔符的StringJoiner对象 StringJoiner joiner = new StringJoiner(delimiter); for (CharSequence cs: elements) { // 拼接字符 joiner.add(cs); } return joiner.toString(); }
查看StringJoiner源码
// 前缀 private final String prefix; // 分隔符 private final String delimiter; // 后缀 private final String suffix; // 值 private StringBuilder value; /** * 构造器 */ public StringJoiner(CharSequence delimiter) { this(delimiter, "", ""); } 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 add(CharSequence newElement) { prepareBuilder().append(newElement); return this; } // 预拼接value private StringBuilder prepareBuilder() { // value已加前缀 if (value != null) { // 此时添加分隔符 value.append(delimiter); } else { // value未加前缀时需要先添加前缀 value = new StringBuilder().append(prefix); } return value; } //重写了toString 方法 @Override public String toString() { if (value == null) { // value未进行任何字符拼接时反悔emptyValue return emptyValue; } else { // 后缀为""字符时,直接返回value if (suffix.equals("")) { return value.toString(); } else { // 获取value未拼接后缀的长度 int initialLength = value.length(); String result = value.append(suffix).toString(); // reset value to pre-append initialLength // 此处是为了保证value.toString()为未拼接后缀前的字符串 value.setLength(initialLength); return result; } } }
使用方式
String delimiter = "-"; String[] elements = {"JDK", "8", "String", "join"}; List<String> list = new ArrayList<String>(Arrays.asList(elements)); System.out.println(String.join(delimiter, elements)); System.out.println(String.join(delimiter, "JDK", "8", "String", "join")); System.out.println(String.join(delimiter, list));
输出结果