StringJoiner

  • 属性说明
/**
* StringJoiner 使用指定的分割符将多个字符串进行拼接,并可指定前缀和后缀
*
* @see java.util.stream.Collectors#joining(CharSequence)
* @see java.util.stream.Collectors#joining(CharSequence, CharSequence, CharSequence)
* @since 1.8
*/
public final class StringJoiner {
/**
* 前缀
*/
private final String prefix; /**
* 分割符
*/
private final String delimiter; /**
* 后缀
*/
private final String suffix; /** 持续添加的字符串数组 */
private String[] elts; /** 已添加的字符串个数 */
private int size; /** 所有字符串的总长度,包括前缀和后缀 */
private int len; /**
* 空值
*
* When null, prefix + suffix is used as the empty value.
*/
private String emptyValue;
  • 实例化
    /**
* 创建分割符为 delimiter,前缀和后缀都为 "" 的 StringJoiner 对象
*
* @param delimiter 分割符
*/
public StringJoiner(CharSequence delimiter) {
this(delimiter, "", "");
} /**
* 创建指定分割符、前缀、后缀的 StringJoiner
*
* @param delimiter 用于连接字符串的分隔符
* @param prefix 前缀字符序列
* @param suffix 后缀字符序列
*/
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();
}
  • 追加字符串
    /**
* 追加字符串 newElement 到此 StringJoiner 中
*
* @param newElement 追加的新元素
*/
public StringJoiner add(CharSequence newElement) {
final String elt = String.valueOf(newElement);
// 1)创建长度为 8 的初始缓冲区
if (elts == null) {
elts = new String[8];
} else {
// 如果已满,则执行双倍扩容
if (size == elts.length) {
elts = Arrays.copyOf(elts, 2 * size);
}
// 记录总字符数
len += delimiter.length();
}
// 记录总字符数
len += elt.length();
// 写入目标元素
elts[size++] = elt;
return this;
}
  • 返回此 StringJoiner 的字符串表示
    /**
* 返回此 StringJoiner 的字符串表示
*/
@Override
public String toString() {
final String[] elts = this.elts;
// 1)尝试返回空值
if (elts == null && emptyValue != null) {
return emptyValue;
}
final int size = this.size;
final int addLen = prefix.length() + suffix.length();
// 如果未指定前缀和后缀
if (addLen == 0) {
// 完成字符串拼接
compactElts();
return size == 0 ? "" : elts[0];
}
final String delimiter = this.delimiter;
final char[] chars = new char[len + addLen];
int k = getChars(prefix, chars, 0);
if (size > 0) {
k += getChars(elts[0], chars, k);
for (int i = 1; i < size; i++) {
k += getChars(delimiter, chars, k);
k += getChars(elts[i], chars, k);
}
}
k += getChars(suffix, chars, k);
return new String(chars);
} private void compactElts() {
// 完成字符串拼接
if (size > 1) {
final char[] chars = new char[len];
// 写入第一个字符串
int i = 1, k = getChars(elts[0], chars, 0);
do {
// 写入分割符
k += getChars(delimiter, chars, k);
// 写入后一个字符串
k += getChars(elts[i], chars, k);
elts[i] = null;
} while (++i < size);
size = 1;
elts[0] = new String(chars);
}
}

StringJoiner 源码阅读的更多相关文章

  1. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  2. 【原】FMDB源码阅读(二)

    [原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...

  3. 【原】FMDB源码阅读(一)

    [原]FMDB源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 说实话,之前的SDWebImage和AFNetworking这两个组件我还是使用过的,但是对于 ...

  4. 【原】AFNetworking源码阅读(六)

    [原]AFNetworking源码阅读(六) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这一篇的想讲的,一个就是分析一下AFSecurityPolicy文件,看看AF ...

  5. 【原】AFNetworking源码阅读(五)

    [原]AFNetworking源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中提及到了Multipart Request的构建方法- [AFHTTP ...

  6. 【原】AFNetworking源码阅读(四)

    [原]AFNetworking源码阅读(四) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇还遗留了很多问题,包括AFURLSessionManagerTaskDe ...

  7. 【原】AFNetworking源码阅读(三)

    [原]AFNetworking源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇的话,主要是讲了如何通过构建一个request来生成一个data tas ...

  8. 【原】AFNetworking源码阅读(二)

    [原]AFNetworking源码阅读(二) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中我们在iOS Example代码中提到了AFHTTPSessionMa ...

  9. 【原】AFNetworking源码阅读(一)

    [原]AFNetworking源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 AFNetworking版本:3.0.4 由于我平常并没有经常使用AFNetw ...

随机推荐

  1. deep_learning_Function_reduction_indices的用法

    在tf.reduce_sum等函数中,有一个reduction_indices参数,表示函数的处理维度. 当没有reduction_indices这个参数,此时该参数取默认值None,将把input_ ...

  2. xtrabackup的使用

    Percona-xtrabackup是 Percona公司开发的一个用于MySQL数据库物理热备的备份工具. 一.安装xtrabackup 采用rpm包的方式进行安装 [root@server- ~] ...

  3. Task扩展方法取消操作

    /// <summary> /// 任务扩展,传入取消操作 /// </summary> public static class TaskExtensionDemo { //因 ...

  4. 【2019中国大学生程序设计竞赛-女生专场】C - Function

    原题 韦神提供的思路orz 首先一个显然的性质,所有的c可以提出来,方程变成ax^2+bx的形式 因为x的值是离散的,而m的值又不大 所以一开始让x都为1(注意!x是正整数),然后每次挑一个x让他加一 ...

  5. BZOJ2144 跳跳棋[建模+LCA]

    思维题,思路比较神仙. 个人思路过程:个人只想到了只要中间棋子开始向外跳了,以后就不应该向内跳了,这样很蠢.所以应该要么先向内跳一会,要么直接开始中间的向外跳.不知道怎么处理,就卡住了. 20pts: ...

  6. 解决laydate动态设置初始值的问题

    //初始化//注意:我这里是时间范围选择,所以定义了range属性.var timeScope = laydate.render({ elem: '#time_scope', range: '~', ...

  7. js高阶函数汇总

    map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值,函数按照原始数组元素顺序依次处理元素. 注意: map() 不会对空数组进行检测. 注意: map() 不会改变原始数组. ...

  8. 解决nginx无法访问的问题

    解决nginx无法访问的问题 解决方案-->恢复Nginx默认配置: cd /usr/local/nginx/conf rm nginx.conf cp nginx.conf.default n ...

  9. Redis介绍、安装、配置

    NoSQL介绍 NoSQL(NoSQL=Not Only SQL),意为反SQL运动,是一项全新的数据库革命性运动.指的是非关系型数据库,解决了传统的关系型数据库,难以解决的超大规模和高并发的的问题 ...

  10. Acwing-201-可见的点(数学, 欧拉函数)

    链接: https://www.acwing.com/problem/content/description/203/ 题意: 在一个平面直角坐标系的第一象限内,如果一个点(x,y)与原点(0,0)的 ...