/**
* @method: skipNulls
* @means: 去调为Null的连接
*/
Joiner joiner = Joiner.on("; ").skipNulls();
String joinStr = joiner.join("Harry", null, "Ron", "Hermione");
//return info:Harry; Ron; Hermione
System.out.println(joinStr);
String listStr =Joiner.on(",").join(Arrays.asList(1, 5, 7));
//return info:"1,5,7"
System.out.println(listStr);
public static Joiner on(String separator) {
return new Joiner(separator);
}
on:以什么为分隔符
Joiner joiner = Joiner.on("; ")
public final String join(Object[] parts) {
return join(Arrays.asList(parts));
}
数组——>list(Iterable 实现了的)
public final String join(@Nullable Object first, @Nullable Object second, Object... rest) {
//iterable转换为List数组,但是没有进行空间的复制
return join(iterable(first, second, rest));
}
//这个是继承JDK的抽象List新创建一个list匿名类,没有进行数据复制操作!
private static Iterable
List->Iterable接口(可以forEach…)
public final String join(Iterable< ?> parts) {
return join(parts.iterator());
}
Iterable调用->Iterator接口(Iterator是Iterable接口的一个成员变量)
public final String join(Iterator< ?> parts) {
return appendTo(new StringBuilder(), parts).toString();
}
然后调用appendTo成员变量进行处理。
之前的处理的都是为了各种类型的数据而进行的构造相互之间调用,和设置分隔符on方法
private final String separator,这个是唯一的一个成员变量的信息。appendTo方法处理将所有的字符串按照给定的格式进行处理。append也是一样的有各种类型的append方法将各种类型的数据进行转换,因为这个要被子类进行覆盖处理哦,这样就可以不要Null的或者处理map等等。
public final StringBuilder appendTo(
StringBuilder builder, @Nullable Object first, @Nullable Object second, Object... rest) {
return appendTo(builder, iterable(first, second, rest));
}
public final StringBuilder appendTo(StringBuilder builder, Iterable> parts) {
return appendTo(builder, parts.iterator());
}
public final StringBuilder appendTo(StringBuilder builder, Iterator> parts) {
try {
appendTo((Appendable) builder, parts);
} catch (IOException impossible) {
throw new AssertionError(impossible);
}
return builder;
}
public A appendTo(A appendable, Iterator> parts) throws IOException {
checkNotNull(appendable);
if (parts.hasNext()) {
appendable.append(toString(parts.next()));
while (parts.hasNext()) {
appendable.append(separator);
appendable.append(toString(parts.next()));
}
}
return appendable;
}
//不能为null
CharSequence toString(Object part) {
checkNotNull(part); // checkNotNull for GWT (do not optimize).
return (part instanceof CharSequence) ? (CharSequence) part : part.toString();
}
匿名类好像Guava非常喜欢使用这个东西,特别是在方法之中使用这个玩意
private Joiner(Joiner prototype) {
this.separator = prototype.separator;
}
public Joiner skipNulls() {
return new Joiner(this) {
@Override
//覆盖最后的一个实现,其他都一样的!
public A appendTo(A appendable, Iterator< ?> parts) throws IOException {
checkNotNull(appendable, "appendable");
checkNotNull(parts, "parts");
//两次遍历的意义就是,找到第一个null之后再去添加分隔符
while (parts.hasNext()) {
Object part = parts.next();
if (part != null) {
appendable.append(Joiner.this.toString(part));
break;
}
}
while (parts.hasNext()) {
Object part = parts.next();
if (part != null) {
appendable.append(separator);
appendable.append(Joiner.this.toString(part));
}
}
return appendable;
}
//返回一种类型的Joiner不能再使用第二种类型的了
@Override
public Joiner useForNull(String nullText) {
throw new UnsupportedOperationException("already specified skipNulls");
}
@Override
public MapJoiner withKeyValueSeparator(String kvs) {
throw new UnsupportedOperationException("can't use .skipNulls() with maps");
}
};
}
这个其实就是覆盖toString哈哈,使用一种之后能在使用其他的了
public Joiner useForNull(final String nullText) {
checkNotNull(nullText);
return new Joiner(this) {
@Override
CharSequence toString(@Nullable Object part) {
return (part == null) ? nullText : Joiner.this.toString(part);
}
@Override
public Joiner useForNull(String nullText) {
throw new UnsupportedOperationException("already specified useForNull");
}
@Override
public Joiner skipNulls() {
throw new UnsupportedOperationException("already specified useForNull");
}
};
}
例子:这个我们估计经常会使用这种的样子的字符串
name=doctor,sex=man这种数据估计可以经常看到吧!
Map<String, String> map = Maps.newLinkedHashMap();
map.put("name", "doctor");
map.put("sex", "man");
/**
* @method: withKeyValueSeparator
* @means: 将key使用什么分割
* date: 2017/4/7
* author: wangji
*/
String join = Joiner.on(",").withKeyValueSeparator("=").join(map);
//return info: name=doctor,sex=man
System.out.println(join);
MapJoiner没有进行继承,而是使用了组合模式,因为加入数据的方式变化了,不会可能是List之类的数据只能是Entry数组,或者Map接口,所以join变化了,但是append几乎还是以前的数据信息,进行简单的变化,处理数据的时候使用代理使用原来的那个joiner的方法,比如这里还可以将Null的值替换呢,就是使用了joiner.useForNull(nullText)
public static final class MapJoiner {
private final Joiner joiner;
private final String keyValueSeparator;
private MapJoiner(Joiner joiner, String keyValueSeparator) {
this.joiner = joiner; // only "this" is ever passed, so don't checkNotNull
this.keyValueSeparator = checkNotNull(keyValueSeparator);
}
public A appendTo(A appendable, Map, ?> map) throws IOException {
return appendTo(appendable, map.entrySet());
}
public StringBuilder appendTo(StringBuilder builder, Map, ?> map) {
return appendTo(builder, map.entrySet());
}
public String join(Map, ?> map) {
return join(map.entrySet());
}
public A appendTo(A appendable, Iterable extends Entry, ?>> entries)
throws IOException {
return appendTo(appendable, entries.iterator());
}
public A appendTo(A appendable, Iterator extends Entry, ?>> parts)
throws IOException {
checkNotNull(appendable);
if (parts.hasNext()) {
Entry, ?> entry = parts.next();
//这里处理了两个分割符,一个来自外围的代理,一个是map的key的分割。
appendable.append(joiner.toString(entry.getKey()));
appendable.append(keyValueSeparator);
appendable.append(joiner.toString(entry.getValue()));
while (parts.hasNext()) {
appendable.append(joiner.separator);
Entry, ?> e = parts.next();
appendable.append(joiner.toString(e.getKey()));
appendable.append(keyValueSeparator);
appendable.append(joiner.toString(e.getValue()));
}
}
return appendable;
}
public StringBuilder appendTo(StringBuilder builder, Iterator extends Entry, ?>> entries) {
try {
appendTo((Appendable) builder, entries);
} catch (IOException impossible) {
throw new AssertionError(impossible);
}
return builder;
}
public String join(Iterable extends Entry, ?>> entries) {
return join(entries.iterator());
}
public String join(Iterator extends Entry, ?>> entries) {
return appendTo(new StringBuilder(), entries).toString();
}
//将NULL的值进行替换掉处理!
public MapJoiner useForNull(String nullText) {
return new MapJoiner(joiner.useForNull(nullText), keyValueSeparator);
}
}