Splitter
The method provided by Java String split split, split source follows.
public String[] split(String regex, int limit) {
char ch = 0;
// 1. 如果regex只有一位且regex不是列出来的这些特殊字符".$|()[{^?*+\\"
// 2. 如果regex只有两位且第一位为转义字符,第二位字符小于0或者大于9并且小于a或者大于z并且小于A或者大于Z
// 3. 与编码相关
if (((regex.value.length == 1 &&
".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
(regex.length() == 2 &&
regex.charAt(0) == '\\' &&
(((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&
((ch-'a')|('z'-ch)) < 0 &&
((ch-'A')|('Z'-ch)) < 0)) &&
(ch < Character.MIN_HIGH_SURROGATE ||
ch > Character.MAX_LOW_SURROGATE)) {
int off = 0;
int next = 0;
boolean limited = limit > 0;
ArrayList<String> list = new ArrayList<>();
while ((next = indexOf(ch, off)) != -1) {
if (!limited || list.size() < limit - 1) {
list.add(substring(off, next));
off = next + 1;
} else { // last one
//assert (list.size() == limit - 1);
list.add(substring(off, value.length));
off = value.length;
break;
}
}
// If no match was found, return this
if (off == 0)
return new String[]{this};
// Add remaining segment
if (!limited || list.size() < limit)
list.add(substring(off, value.length));
// Construct result
int resultSize = list.size();
if (limit == 0) {
while (resultSize > 0 && list.get(resultSize - 1).length() == 0) {
resultSize--;
}
}
String[] result = new String[resultSize];
return list.subList(0, resultSize).toArray(result);
}
return Pattern.compile(regex).split(this, limit);
}
Splitter
Java split method ignores empty content, but does not ignore Guava Splitter can also be selectively ignored.
use
- Construction method
With Joinner, private construction method, use the static method returns Splitter object.
// 私有构造方法
private Splitter(Strategy strategy) {
this(strategy, false, CharMatcher.none(), Integer.MAX_VALUE);
}
private Splitter(Strategy strategy, boolean omitEmptyStrings, CharMatcher trimmer, int limit) {
this.strategy = strategy;
this.omitEmptyStrings = omitEmptyStrings;
this.trimmer = trimmer;
this.limit = limit;
}
// 静态方法
// 使用指定字符进行分割
public static Splitter on(char separator)
// 使用指定类进行分割
public static Splitter on(final CharMatcher separatorMatcher)
// 使用指定字符串进行分割
public static Splitter on(final String separator)
// 使用指定正则表达式进行分割
public static Splitter on(Pattern separatorPattern) {
return on(new JdkPattern(separatorPattern));
}
private static Splitter on(final CommonPattern separatorPattern)
Splitter has achieved in a very clear strategy model and template model, there are various methods Shenhuqiji coverage, as well as Guava prestigious iterative technique and lazy evaluation. Spliter property has four members, as follows.
// 用于描述分割之后内容前后指定字符的策略,例如trimResults将策略定为分割之后结果前后空格删除
private final CharMatcher trimmer;
// 是否删除空字符串
private final boolean omitEmptyStrings;
// 拆分之后的结果个数
private final int limit;
// 实现的策略模式
private final Strategy strategy;
Splitter strategy is an interface mode, only one iterator method, and passing the string Splitter objects to be resolved, the iterator returns a string.
private interface Strategy {
Iterator<String> iterator(Splitter splitter, CharSequence toSplit);
}
- Segmentation
The split method, a split sequence, iterator returns a string.
public Iterable<String> split(final CharSequence sequence) {
checkNotNull(sequence);
return new Iterable<String>() {
@Override
public Iterator<String> iterator() {
return splittingIterator(sequence);
}
@Override
public String toString() {
return Joiner.on(", ")
.appendTo(new StringBuilder().append('['), this)
.append(']')
.toString();
}
};
}
private Iterator<String> splittingIterator(CharSequence sequence) {
return strategy.iterator(this, sequence);
}
splitToList method, split sequence returns List.
@Beta
public List<String> splitToList(CharSequence sequence) {
checkNotNull(sequence);
Iterator<String> iterator = splittingIterator(sequence);
List<String> result = new ArrayList<String>();
// 这里采用惰性求值的技巧,在最后调用splitToList时才将结果添加到result中
while (iterator.hasNext()) {
result.add(iterator.next());
}
return Collections.unmodifiableList(result);
}
- Other methods
omitEmptyStrings method removes empty string results.
public Splitter omitEmptyStrings() {
return new Splitter(strategy, true, trimmer, limit);
}
trimResults, stripping elements about the empty string, the middle string is not empty the contents removed.
public Splitter trimResults() {
return trimResults(CharMatcher.whitespace());
}
public Splitter trimResults(CharMatcher trimmer) {
checkNotNull(trimmer);
return new Splitter(strategy, omitEmptyStrings, trimmer, limit);
}
fixedLength method, according to the number of sub-divided character string.
public static Splitter fixedLength(final int length) {
checkArgument(length > 0, "The length may not be less than 1");
return new Splitter(
new Strategy() {
@Override
public SplittingIterator iterator(final Splitter splitter, CharSequence toSplit) {
return new SplittingIterator(splitter, toSplit) {
@Override
public int separatorStart(int start) {
int nextChunkStart = start + length;
return (nextChunkStart < toSplit.length() ? nextChunkStart : -1);
}
@Override
public int separatorEnd(int separatorPosition) {
return separatorPosition;
}
};
}
});
}
Method limit, a maximum limit divided substrings.
public Splitter limit(int limit) {
checkArgument(limit > 0, "must be greater than zero: %s", limit);
return new Splitter(strategy, omitEmptyStrings, trimmer, limit);
}
onPattern method, according to a regular expression split.
@GwtIncompatible // java.util.regex
public static Splitter onPattern(String separatorPattern) {
// 返回按正则表达式进行分割的Splitter
return on(Platform.compilePattern(separatorPattern));
}
withKeyValueSeparator method, the specified delimiter string is divided into a map.
public MapSplitter withKeyValueSeparator(String separator) {
return withKeyValueSeparator(on(separator));
}
@Beta
public MapSplitter withKeyValueSeparator(Splitter keyValueSplitter) {
return new MapSplitter(this, keyValueSplitter);
}
// MapSplitter是Sppiter中的一个内部类,内部覆写了split方法
@Beta
public static final class MapSplitter {
private static final String INVALID_ENTRY_MESSAGE = "Chunk [%s] is not a valid entry";
private final Splitter outerSplitter;
private final Splitter entrySplitter;
private MapSplitter(Splitter outerSplitter, Splitter entrySplitter) {
this.outerSplitter = outerSplitter; // only "this" is passed
this.entrySplitter = checkNotNull(entrySplitter);
}
public Map<String, String> split(CharSequence sequence) {
Map<String, String> map = new LinkedHashMap<String, String>();
for (String entry : outerSplitter.split(sequence)) {
Iterator<String> entryFields =
entrySplitter.splittingIterator(entry);
checkArgument(entryFields.hasNext(), INVALID_ENTRY_MESSAGE, entry);
String key = entryFields.next();
checkArgument(!map.containsKey(key), "Duplicate key [%s] found.", key);
checkArgument(entryFields.hasNext(), INVALID_ENTRY_MESSAGE, entry);
String value = entryFields.next();
map.put(key, value);
checkArgument(!entryFields.hasNext(), INVALID_ENTRY_MESSAGE, entry);
}
return Collections.unmodifiableMap(map);
}
}