Guava ImmutableMap Builder语法

Dur*_*dal 16 java immutability guava

我一直在使用番石榴的已经ImmutableMapBuilder一段时间没有过多考虑如何/为什么它的工作原理.我一直在以Javadoc描述的方式使用构建器:

ImmutableMap<String, Integer> WORD_TO_INT =
          new ImmutableMap.Builder<String, Integer>()
              .put("one", 1)
              .put("two", 2)
              .put("three", 3)
              .build();
Run Code Online (Sandbox Code Playgroud)

我也在其他地方看到过这种语法的例子:

ImmutableMap<String,Integer> myMap = ImmutableMap.<String, Integer>builder()
    .put("one", 1) 
    .put("two", 2) 
    .put("three", 3) 
    .build();
Run Code Online (Sandbox Code Playgroud)

两者似乎都产生完全相同的结果.

快速浏览一下ImmutableMap 表明builder()第二个例子中的静态调用返回:new Builder<K, V>()

这两种方法之间似乎没有任何功能差异.

引擎盖下有什么不同吗?有理由偏好其中一个吗?

编辑:添加字节码差异.

除了一行之外,生成的字节码几乎相同:

方法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]
     ........
Run Code Online (Sandbox Code Playgroud)

方法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]
     ........
Run Code Online (Sandbox Code Playgroud)

在那之后他们几乎是一样的,鉴于源差异,第一行是不同的,但我不确定为什么第一个调用dup,第二个调用不.

Bor*_*der 18

不,他们是完全相同的.第一种语法的原因是它制作了一个很好的单行.

第二种语法的原因是您可能有循环或其他流控制,您可能需要传递它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));
    }
}
Run Code Online (Sandbox Code Playgroud)

在你说之前,是的FluentIterable,在这种情况下可能会更好 - 但这只是一个例子.

  • @MagicMan,你没有提供完整的字节码列表,但我相信在第一个例子中``dup`后面有`invokespecial ... ImmutableMap $ Builder.<init>()`.这正是为什么需要`dup`的原因.在Java构造中是两阶段过程:首先,通过`new`分配新内存,然后在该内存上调用构造函数方法(`<init>`).所以`dup`ed堆栈元素由构造函数使用. (2认同)