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. 第十三章·Kibana深入-使用地图统计客户端IP

    地址库 在ELK中,我们可以使用地址库,来对IP进行分析,对日志进行分析,在ELKstack中只有Logstash可以做到,但是出图,是Kibana来出的,所以我们首先需要下载地址库数据文件,然后对L ...

  2. JDBC模拟登陆及SQL语句防注入问题

    实现模拟登陆效果:基于表Tencent package boom; import java.sql.Connection; import java.sql.DriverManager; import ...

  3. mysql数据库:分表、多表关联、外键约束、级联操作

    一.分表.外键.级联.多对一 二.多对多 三.一对一 一.分表.外键.级联.多对一 将部门数据与员工数据放到同一张表中会造成 数据重复 结构混乱 扩展维护性差 需要分表 create table de ...

  4. Redis03——Redis架构

    Redis架构 1.1.问题 redis是单线程,单实例,为什么并发那么多,依旧很快呢? 回答:因为调用了系统内核的epoll 1.2.Linux的早期版本 Linux有Linux kernal,我们 ...

  5. Datasets and Evaluation Metrics used in Recommendation System

    Movielens and Netflix remain the most-used datasets. Other datasets such as Amazon, Yelp and CiteUli ...

  6. TF启程

    我第一次开始接触到TensorFlow大概是去年五月份,大三下,如果一年多已过,我却还在写启程..这进度,实在汗颜.. 一个完整的tensorflow程序可以分为以下几部分: Inputs and P ...

  7. linux内核 同步

    锁 linux本身实现了集中锁机制,各种锁机制之间的差别是,当锁已经被其他线程持有的时候,一些锁使用自旋的方式来等待,另外一些锁会当当前线程改变为睡眠状态然后等待被唤醒. 锁的争用 如果一个锁处于高度 ...

  8. LOAD DATA INFILE & mysqlimport

    +++++++++++++++++++++++++++++++++++++++++++++mysqlimport++++++++++++++++++++++++++++++++++++++++++++ ...

  9. c++使用初始化列表来初始化字段

    #include<iostream> using namespace std; class Student1 { private: int _a; int _b; public: void ...

  10. 【转】分布式文件系统FastDFS架构剖析

    FastDFS是一款类Google FS的开源分布式文件系统,它用纯C语言实现,支持Linux.FreeBSD.AIX等UNIX系统.它只能通过专有API对文件进行存取访问,不支持POSIX接口方式, ...