私はGuavaのImmutableMap
をBuilder
と一緒にしばらく使用していますが、それがどのように/なぜ機能するのかについてはあまり考えていません。 Javadoc で説明されている方法でビルダーを使用しています:
_ImmutableMap<String, Integer> Word_TO_INT =
new ImmutableMap.Builder<String, Integer>()
.put("one", 1)
.put("two", 2)
.put("three", 3)
.build();
_
この構文の例 elsewhere on SO:
_ImmutableMap<String,Integer> myMap = ImmutableMap.<String, Integer>builder()
.put("one", 1)
.put("two", 2)
.put("three", 3)
.build();
_
どちらもまったく同じ結果をもたらすようです。
ImmutableMap
source をひと目見ると、2番目の例の静的builder()
呼び出しが次のようになっていることがわかります。new Builder<K, V>()
2つの方法の間に機能的な違いはないようです。
ボンネットの下で何か違いはありますか?どちらかを好む理由はありますか?
編集:バイトコードの違いを追加します。
生成されたバイトコードは、1行を除いてほとんど同じです。
方法1(_Builder<K,V>
_):
_static {};
0 new com.google.common.collect.ImmutableMap$Builder [12]
3 dup
4 invokespecial com.google.common.collect.ImmutableMap$Builder() [14]
7 ldc <String "key1"> [17]
........
_
方法2:(<K,V>builder()
)
_static {};
0 invokestatic com.google.common.collect.ImmutableMap.builder() : com.google.common.collect.ImmutableMap$Builder [12]
3 ldc <String "key1"> [18]
........
_
その後、それらはほとんど同じになり、ソースの違いを考えると最初の行が異なることは理にかなっていますが、最初の行がdup
を呼び出し、2番目の行が呼び出さない理由はわかりません。
いいえ、同じです。最初の構文の理由は、それが素敵なワンライナーになるからです。
2番目の構文の理由は、ループまたは他のフロー制御がある可能性があるため、Builder
を渡す必要がある場合があります。
例えば:
public static void main(final String[] args) throws Exception {
final ImmutableList.Builder<Integer> lb = ImmutableList.builder();
for (final String arg : args) {
lb.add(Integer.parseInt(arg));
}
}
そして、あなたがそれを言う前に、はい、この場合はおそらくFluentIterable
の方が良いでしょう-しかし、それは単なる例です。
javadoc で述べられているように、生成されたビルダーは、ImmutableMap.Builderコンストラクターによって作成されたビルダーと同等です。
Builderパターンを適用するときは、このようなメソッドを作成することをお勧めします。これは流暢な使い方を提供し、「シンタックスシュガー」と見なすことができます。