Java8 で String クラスに、static な join メソッドが追加されていました。
使い方はとってもシンプル。
String message = String.join("-", "Java", "is", "cool"); // message には "Java-is-cool" が代入されています。
引数に、任意の数の CharSequence *1、もしくは Iterable<? extends CharSequence> 型のオブジェクトを渡すだけ。
実装
処理は、ほどんど java.util.StringJoiner クラス*2が行っています。
/** * {@code CharSequence elements} のコピーを指定の {@code delimiter} で * 結合した文字列を返します。 * * <blockquote>For example, * <pre>{@code * String message = String.join("-", "Java", "is", "cool"); * // message には "Java-is-cool" が代入されています。 * }</pre></blockquote> * * もし要素が null なら、{@code "null"}を追加します。 * * @param delimiter 各要素を区切る区切り文字 * @param elements ひとつに結合する要素 * * @return {@code elements} が {@code delimiter} で区切られた、 * 新しい {@code String} * * @throws NullPointerException {@code delimiter} または {@code elements} が * {@code null} のとき * * @see java.util.StringJoiner * @since 1.8 */ public static String join(CharSequence delimiter, CharSequence... elements) { Objects.requireNonNull(delimiter); Objects.requireNonNull(elements); // Number of elements not likely worth Arrays.stream overhead. StringJoiner joiner = new StringJoiner(delimiter); for (CharSequence cs: elements) { joiner.add(cs); } return joiner.toString(); }
StringJoiner は public なクラスなので、独自に使うこともできるようになっています。
こっちを直接使うと、prefix, suffix も指定できるようです。
その StringJoiner 自体はとてもシンプルです。
以下は、今回の話に関連しているところだけ抜き出したものです。遅延初期化していたり、そもそも結合処理自体をひとつのクラスとして実装しているなど、細かく工夫されているなーと感じました。
public final class StringJoiner { private final String prefix; private final String delimiter; private final String suffix; private StringBuilder value; public StringJoiner(CharSequence delimiter) { this(delimiter, "", ""); } public StringJoiner(CharSequence delimiter, CharSequence prefix, CharSequence suffix) { // (省略) } public StringJoiner add(CharSequence newElement) { prepareBuilder().append(newElement); return this; } private StringBuilder prepareBuilder() { if (value != null) { value.append(delimiter); } else { value = new StringBuilder().append(prefix); } return value; } }
まとめ
これでプロジェクトごとに毎回 join メソッドを書かずに済みますね!