一、使用例子
public class TestJoin {
public static void main(String[] args) {
List<String> list=new ArrayList<String>();
list.add("a");
list.add("b");
String listStr=StringUtils.join(list,",");
System.out.println(listStr);
}
}
二、代码解析
public static String join(Collection collection, String separator) {
//判断集合是否为空
if (collection == null) {
return null;
}
//调用连接函数
return join(collection.iterator(), separator);
}
public static String join(Iterator iterator, String separator) {
//在构建缓冲区之前,处理null、0和1元素
if (iterator == null) {
return null;
}
//判断集合是否有值
if (!iterator.hasNext()) {
return EMPTY;//EMPTY = "";
}
//获取第一节点的值
Object first = iterator.next();
if (!iterator.hasNext()) {
return ObjectUtils.toString(first);
}
// 两个或多个元素,构建缓冲区
StrBuilder buf = new StrBuilder(256); // Java default is 16, 可能太小了
if (first != null) {
buf.append(first);
}
while (iterator.hasNext()) {
//加入分割符号
if (separator != null) {
buf.append(separator);
}
//加入集合的值
Object obj = iterator.next();
if (obj != null) {
buf.append(obj);
}
}
//返回数据
return buf.toString();
}
//AbstractList中的iterator()方法(ArrayList直接继承了这个方法)使用了一个私有内部成员类Itr,生成一个Itr对象(Iterator接口)返回:
public Iterator<E> iterator() {
return new Itr();
}
//新建迭代器
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
//判断是否还有元素,当前节点和元素总个数比较
public boolean hasNext() {
return cursor != size;
}
//取下一个节点
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> consumer) {
Objects.requireNonNull(consumer);
final int size = ArrayList.this.size;
int i = cursor;
if (i >= size) {
return;
}
final Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[i++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
/**
* 在对一个集合对象进行跌代操作的同时,并不限制对集合对象的元素进行操作
* 这些操作包括一些可能引起跌代错误的add()或remove()等危险操作。
* 在AbstractList中,使用了一个简单的机制来规避这些风险。
* 这就是modCount和expectedModCount的作用所在
*/
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
checkForComodification()方法的作用
(1)主要是用来实现fail-fast机制
有两个线程(线程A,线程B),其中线程A负责遍历list、线程B修改list。
-线程A在遍历list过程的某个时候(此时expectedModCount = modCount=N),线程启动,
同时线程B增加一个元素,这是modCount的值发生改变(modCount + 1 = N + 1)。 线程A继续遍历执行next方法时,
通告checkForComodification方法发现expectedModCount = N , 而modCount = N + 1,两者不等,
这时就抛出ConcurrentModificationException 异常,从而产生fail-fast机制。
(2)在ArrayList的所有涉及结构变化的方法中都增加modCount的值,包括:add()、remove()、addAll()、removeRange()及clear()方法。
这些方法每调用一次,modCount的值就加1。注:add()及addAll()方法的modCount的值是在其中调用的ensureCapacity()方法中增加的。
(3)Itr实现了Iterator()接口,其中也定义了一个int型的属性:expectedModCount,这个属性在Itr类初始化时被赋予ArrayList对象的modCount属性的值。