Guava-String-Joiner

1. Joiner 用法

  • 连接字符串
Joiner joiner = Joiner.on("; ").skipNulls();
joiner.join("Harry", null, "Ron", "Hermione");
  • 使用在对象上
Joiner.on(",").join(Arrays.asList(1, 5, 7)); // returns "1,5,7"
  • joiner实例通常是不可变的,Joiner线程安全,使用静态常量方式:static final

2. Joiner属性

  • 分隔符保存为separator
private final String separator;

3. Appendable接口(jdk)

  • 提供了append方法
    Appendable append(CharSequence csq) throws IOException;
    Appendable append(CharSequence csq, int start, int end) throws IOException;
    Appendable append(char c) throws IOException;

  • 哪些实现了CharSequence
    String
    StringBuiler

3. Joiner方法

1. on
2. appendTo
3. join
4. useForNull
5. skipNulls
6. withKeyValueSeparator
7. toString
8. iterable(私有)

3.1 on

  • 构造函数私有不能调用
private Joiner(String separator) {
    this.separator = (String)Preconditions.checkNotNull(separator);
}
  • on是静态工厂
    • 构造一个Joiner
    • 设置分隔符separator
public static Joiner on(String separator) {
    return new Joiner(separator);
}
public static Joiner on(char separator) {
    return new Joiner(String.valueOf(separator));
}

toSring

  • toString是Joiner内置的方法(获取CharSequence)
    都是生成CharSequence之后连接的
  CharSequence toString(Object part) {
    checkNotNull(part);
    return (part instanceof CharSequence) ? (CharSequence) part : part.toString();
  }

3.2 appendTo

  • 参数及返回值
    1. Appendable (Appendable , Iteratable)
    2. Appendable (Appendable , Iterator)
    3. Appendable (Appendable , Object[])
    4. StringBuilder (StringBuilder, Iterable)
    5. StringBuilder (StringBuilder, Iterator)
    6. StringBuilder (StringBuilder, Object[]))

  • 分析

public <A extends Appendable> A appendTo(A appendable, Iterable<?> parts) throws IOException {
    return appendTo(appendable, parts.iterator());
}

调用的还是Appendable appendTo(Appendable , Iterator)方法
大致是一个parts一个separator的方式

  public <A extends Appendable> 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;
  }
  • append效果演示
   public static void main(String[] args) {
        Joiner joiner = Joiner.on("; ");
        StringBuilder sb = new StringBuilder("----");
        List<String> list = Lists.newArrayList("a","b","c","d");
        sb = joiner.appendTo(sb, list);
        System.out.println(sb.toString());
    }

输出:----a; b; c; d

3.3 withKeyValueSeparator

  • 内部类MapJoiner

  • 属性
    private final Joiner joiner;
    private final String keyValueSeparator;

  • 方法
    1. Appendable (Appendable, Map<?, ?> map))
    2. StringBuilder (StringBuilder, Map<?, ?> map))

    public <A extends Appendable> A appendTo(A appendable, Iterator<? extends Entry<?, ?>> parts)
        throws IOException {
      checkNotNull(appendable);
      if (parts.hasNext()) {
        Entry<?, ?> entry = parts.next();
        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;
    }
  • withKeyValueSeparator方法,能够返回MapJoiner,在这个方法中传入keyValueSeparator
    MapJoiner中,只有在这个方法中传入keyValueSeparator起作用
public MapJoiner withKeyValueSeparator(String keyValueSeparator) {
    return new MapJoiner(this, keyValueSeparator);
  }
  • MapJoiner效果演示:
        Map<String, Integer> map = Maps.newHashMap();
        map.put("a",1);
        map.put("b",2);
        map.put("c",3);
        StringBuilder sb2 = new StringBuilder("----");
        sb2 = joiner.withKeyValueSeparator("+").appendTo(sb2, map);
        System.out.println(sb2.toString());

输出:----a+1; b+2; c+3

3.4 join

  • 具有四种参数,返回都是String
public final String join(Iterable<?> parts)
public final String join(Iterator<?> parts)
public final String join(Object[] parts)
public final String join(@Nullable Object first, @Nullable Object second, Object... rest)
  • 最终都是调用如下的方法:使用StringBuiler构造
  public final String join(Iterator<?> parts) {
    return appendTo(new StringBuilder(), parts).toString();
  }

3.5 useForNull和skipNulls-构造自己时,覆盖自己的某些方法

  • 如果是null会抛异常
  • useForNull重写了toString,useForNull,skipNulls方法
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");
      }
    };
  }
  • skipNulls重写了toString,useForNull,skipNulls方法
  public Joiner skipNulls() {
    return new Joiner(this) {
      @Override
      public <A extends Appendable> A appendTo(A appendable, Iterator<?> parts) throws IOException {
        checkNotNull(appendable, "appendable");
        checkNotNull(parts, "parts");
        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;
      }

      @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");
      }
    };
  }

iterable

  private static Iterable<Object> iterable(
      final Object first, final Object second, final Object[] rest) {
    checkNotNull(rest);
    return new AbstractList<Object>() {
      @Override
      public int size() {
        return rest.length + 2;
      }

      @Override
      public Object get(int index) {
        switch (index) {
          case 0:
            return first;
          case 1:
            return second;
          default:
            return rest[index - 2];
        }
      }
    };
  }

问题joiner.this.toString()??

posted @ 2016-08-09 13:24  zhangshihai1232  阅读(329)  评论(0)    收藏  举报