Question

I browsed some JAVA code made by Google, and I found the ImmutableSet: http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/ImmutableSet.html

They implemented the of() method with several other ways:

public static <E> ImmutableSet<E> of(E e1, E e2);
public static <E> ImmutableSet<E> of(E e1, E e2, E e3);
public static <E> ImmutableSet<E> of(E e1, E e2, E e3, E e4);
public static <E> ImmutableSet<E> of(E e1, E e2, E e3, E e4, E e5);
public static <E> ImmutableSet<E> of(E... elements);

I checked the implementation which is here:https://code.google.com/p/google-collections/source/browse/trunk/src/com/google/common/collect/ImmutableSet.java

There's a create method wiith the following signature:

private static <E> ImmutableSet<E> create(E... elements)

which wraps the

private static <E> ImmutableSet<E> create(Iterable<? extends E> iterable, int count);

method. The public methods just passes the parameters to the create(E... elements) signatured method which finally calls the other create method.

I guess that the public of methods with fixed count of parameter are unnecessary since we have the of(E... elements) method.

My question is that why did they do that like this? Performance? Or it's a pattern?

Thanks.

Was it helpful?

Solution

It can't be related to performance, actually: All the methods delegate to the same creation method, which expects an array anyhow.

My guess is that it is related to warnings. Consider the following, minimal snippet:

import java.util.List;

class ImmutableSet<T>
{
}
public class ParametersTest
{
    public static void main(String[] args)
    {
        List<String> list0 = null;
        List<String> list1 = null;
        of(list0, list1);
    }

    @SuppressWarnings("unchecked")
    public static <E> ImmutableSet<E> of(E e1, E e2) {
        return create(e1, e2);
    }

    public static <E> ImmutableSet<E> of(E... elements) {
        return create(elements);
    }

    private static <E> ImmutableSet<E> create(E... elements) 
    {
        return null;
    }

}

The call to of in the main method is fine: It matches the 2-args-version of the of method. Now comment out the 2-args-version of the of-method. Then the call is still OK, but will directly invoke the varags version. This will cause a generic array to be created, and cause a warning. (This warning is suppressed in the 2-args-version, obviously).

So to summarize, I assume that this is in order to avoid warnings for clients of the library who want to invoke the of method with several objects of a generic type.

Fortunately, things like this will no longer be necessary in the future, thanks to http://docs.oracle.com/javase/7/docs/api/java/lang/SafeVarargs.html

OTHER TIPS

Performance. In order to call the E... version of the method, the caller must allocate a new array. The caller only has to push the args on the stack to call the other methods.

They do it to manage memory in a more efficient way. If you have an immutable collection with a small set of items, it is better to explicitly fix the size of the collection. Otherwise, Java will create a collection of a size that is bigger. E.g: A HashSet, unless specified otherwise will have an intial size of 12 entries.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top