Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combine guava's ImmutableList and varargs

I want create constructor that will take one or more integers and save it into field as ImmutableList. According to "The right way to use varargs to pass one or more arguments" by Bloch's Item 42 I create smt like

class Foo{
    private final ImmutableList<Integer> bar;
    public Foo(Integer first, Integer... other) {
        this.bar = ImmutableList.<Integer>builder()
                .add(first)
                .addAll(Arrays.asList(other))
                .build();
    }
}

Why builder doesn't get generic automatically? And, as it smells. How I can rewrite it?

upd qustion with generics solved. Any suggestions about refactoring are very helpful.

like image 834
Stan Kurilin Avatar asked Dec 25 '10 19:12

Stan Kurilin


2 Answers

Regarding your second question (how to refactor you constructor to make it shorter / more readable), I would do this:

class Foo{
    private final ImmutableList<Integer> bar;
    public Foo(Integer first, Integer... other) {
        this.bar = ImmutableList.copyOf(Lists.asList(first, other));
    }
}

Both Lists.asList methods were designed with this goal in mind, according to their javadoc:

This is useful when a varargs method needs to use a signature such as (Foo firstFoo, Foo... moreFoos), in order to avoid overload ambiguity or to enforce a minimum argument count.

It's also more performant than the ImmutableList.Builder, since it avoids the creation / resizing of a temporary ArrayList inside the Builder.


like image 99
Etienne Neveu Avatar answered Sep 28 '22 09:09

Etienne Neveu


Because the when calling builder() there is no left-hand side of the expression. The compiler cannot infer what type to add there. (It cannot infer it from subsequent method calls)

If you change it to the following, it works:

Builder<Integer> builder = ImmutableList.builder();
this.bar = builder.add(first).addAll(Arrays.asList(other)).build();

However, you can safely retain your current code - it is fine. And even better than the above example (it's shorter)

About the refactoring - why not use .add(first).add(other)? The add method has a varargs version.

like image 25
Bozho Avatar answered Sep 28 '22 10:09

Bozho