静态工厂模式提供了六个静态方法,从上往下分别是:
- 基于字符分隔
- 基于正则表达式分隔
- 字符串分隔
- 它自己的字符匹配器分隔
- 按指定长度划分,必须大于0

最终都会返回splitter对象,Splitter构造方法的参数是一个接口,接口内就一个返回值为字符串迭代器的方法。所以每个静态方法生成splitter对象时都需要实现Strategy接口的方法。
//Splitter构造方法
private Splitter(Strategy strategy) {
this(strategy, false, CharMatcher.none(), Integer.MAX_VALUE);
}
//Strategy接口
private interface Strategy {
Iterator<String> iterator(Splitter splitter, CharSequence toSplit);
}
splitter实现的每个Strategy接口方法,返回值都是SplittingIterator,它是个抽象类继承了AbstractIterator,
而AbstractIterator又继承了Iterator,那此处又得实现SplittingIterator的两个抽象方法,也就是separatorStart和separatorEnd,他们分别指得是:
- separatorStart:参数start就是当前开始的下标值,返回当前下标之后的第一个指定分隔符所在的下标
- separatorEnd:返回separatorStart值+1的值
public static Splitter on(final CharMatcher separatorMatcher) {
checkNotNull(separatorMatcher);
//通过构造方法创建一个Splitter对象
return new Splitter(
//new Strategy接口,实现接口的iterator方法
new Strategy() {
//SplittingIterator类是个抽象类,需要重写抽象方法
@Override
public SplittingIterator iterator(Splitter splitter, final CharSequence toSplit) {
return new SplittingIterator(splitter, toSplit) {
@Override
int separatorStart(int start) {
return separatorMatcher.indexIn(toSplit, start);
}
@Override
int separatorEnd(int separatorPosition) {
return separatorPosition + 1;
}
};
}
});
}
最后计算的核心代码:
@CheckForNull
@Override
protected String computeNext() {
//offset是开始寻找的下标
int nextStart = offset;
while (offset != -1) {
int start = nextStart;
int end;
//返回指定分隔符所在的下标
int separatorPosition = separatorStart(offset);
if (separatorPosition == -1) {
//没找到分隔符,返回-1
end = toSplit.length();
offset = -1;
} else {
//找到分隔符,给offset赋值分隔符下标位置+1,下次就从offset的位置开始寻找
end = separatorPosition;
offset = separatorEnd(separatorPosition);
}
//第一个字符就是分隔符
if (offset == nextStart) {
offset++;
//下次开始的下标值大于需处理的字符长度
if (offset > toSplit.length()) {
offset = -1;
}
continue;
}
//如果调用过splitter.trimResults(CharMatcher trimmer)方法,就会在开头和结尾将匹配的字符也去除
while (start < end && trimmer.matches(toSplit.charAt(start))) {
start++;
}
while (end > start && trimmer.matches(toSplit.charAt(end - 1))) {
end--;
}
//如果执行过splitter.omitEmptyStrings()方法,就会将结果中的空字符串去除
if (omitEmptyStrings && start == end) {
nextStart = offset;
continue;
}
//如果执行过splitter.limit(int i)方法,就会在到达指定下标时停止字符串分隔,将剩下的未分割的字符串都放到数组结果的最后一个元素中
if (limit == 1) {
end = toSplit.length();
offset = -1;
while (end > start && trimmer.matches(toSplit.charAt(end - 1))) {
end--;
}
} else {
limit--;
}
//返回开始-第一个分隔符之前的字符
return toSplit.subSequence(start, end).toString();
}
return endOfData();
}
}
后续通过静态方法返回的splitter对象所执行的方法都是在执行该核心代码。只是在每次执行方法时做一个标记,在执行核心代码时根据标记值判断是否执行,具体详见上方核心代码分析的注释
网友评论