Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the point of overloaded Convenience Factory Methods for Collections in Java 9

Java 9 comes with convenience factory methods for creating immutable lists. Finally a list creation is as simple as:

List<String> list = List.of("foo", "bar"); 

But there are 12 overloaded versions of this method, 11 with 0 to 10 elements, and one with var args.

static <E> List<E>  of(E... elements) 

Same is the case with Set and Map.

Since there is a var args method, what is the point of having extra 11 methods?

What I think is that var-args create an array, so the other 11 methods can skip creation of an extra object and in most cases 0 - 10 elements will do. Is there any other reason for this?

like image 775
ares Avatar asked Jan 29 '17 08:01

ares


People also ask

Which method is added to Set in Java 9?

With Java 9, new factory methods are added to List, Set and Map interfaces to create immutable instances.

What are Collection factory methods in Java?

A collection factory method in Java is a static method that provides a simple way of initializing an immutable Collection<E> . Being immutable, no elements can be added to, removed from, or modified inside the Collection<E> after it is initialized.


2 Answers

From the JEP docs itself -

Description -

These will include varargs overloads, so that there is no fixed limit on the collection size. However, the collection instances so created may be tuned for smaller sizes. Special-case APIs (fixed-argument overloads) for up to ten of elements will be provided. While this introduces some clutter in the API, it avoids array allocation, initialization, and garbage collection overhead that is incurred by varargs calls. Significantly, the source code of the call site is the same regardless of whether a fixed-arg or varargs overload is called.


Edit - To add motivation and as already mentioned in the comments by @CKing too :

Non-Goals -

It is not a goal to support high-performance, scalable collections with arbitrary numbers of elements. The focus is on small collections.

Motivation -

Creating a small, unmodifiable collection (say, a set) involves constructing it, storing it in a local variable, and invoking add() on it several times, and then wrapping it.

Set<String> set = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("a", "b", "c"))); 

The Java 8 Stream API can be used to construct small collections, by combining stream factory methods and collectors.

// Java 8 Set<String> set1 = Collections.unmodifiableSet(Stream.of("a", "b", "c").collect(Collectors.toSet())); 

Much of the benefit of collection literals can be gained by providing library APIs for creating small collection instances, at significantly reduced cost and risk compared to changing the language. For example, the code to create a small Set instance might look like this:

// Java 9  Set set2 = Set.of("a", "b", "c"); 
like image 61
Naman Avatar answered Sep 29 '22 13:09

Naman


As you suspected, this is a performance enhancement. Vararg methods create an array "under the hood", and having method which take 1-10 arguments directly avoids this redundant array creation.

like image 32
Mureinik Avatar answered Sep 29 '22 13:09

Mureinik