mike-neckのブログ

Java or Groovy or Swift or Golang

Java 8 で追加された StringJoiner が意外と便利っぽい

表記のとおりです。

java.util.StringJoinerString.join(CharSequence, CharSequence...)などで用いられているクラスですが、そのまま使ってもなかなか便利そうです。

StringJoiner.metaClass.define {
    leftShift = {Object o ->
        delegate.add(o.toString())
    }
}

def list = ['foo', 'bar', 'baz']

def sj = new StringJoiner(', ', '[', ']')
list.each {sj << it}

assert "[foo, bar, baz]" == sj.toString()

Groovy使ってサンプル書いていますが、prefixとsuffixを設定して文字列に整形できるのはなかなか便利そうです。

最近はtoString()の実装などはIDEにお任せするか、Lombok使うのが普通ですが、こだわりがあって自前で実装するときはStringJoinerを使うと便利そうな気がします。

class Player {
    final String firstName, lastName
    Player(String f, String l) {
        firstName = f
        lastName = l
    }
    @Override String toString() {
        def sj = new StringJoiner(',', 'Player{', '}')
        sj.merge(new StringJoiner(':').add('lastName').add(lastName))
                .merge(new StringJoiner(':').add('firstName').add(firstName))
        sj.toString()
    }
}

assert new Player('花子', '山田').toString() == 'Player{lastName:山田,firstName:花子}'

ちなみにパフォーマンスはというと…

Java8時代の文字列連結まとめ - きしだのはてな

すでにきしださんが調べてて、

速度こだわるなら、メモリちゃんと確保したStringBuilderですねぇ・・・

ちょっと、「Java8からはStringBuilderよりStreamやで!」とか「StringJoiner使おう」とか無条件には言えそうにない。

だそうです(´・ω・`)