4

My question may sound silly, but please, read the whole question first.

I wonder for a long time, why ArrayList and other classes implementing List, Set etc., doesn't provide a simple constructor accepting the variable count of parameters?

List<Integer> list = new ArrayList<>(1, 2, 3);

This looks simple and obvious. Java 9 provides newly List.of() static factory method which only copies the same what Apache Utils and Guava have introduced. We are forced to use the verbose workarounds.

List<Integer> list = Arrays.asList(1, 2, 3);
List<Integer> list = Stream.of(1, 2, 3).collect(Collectors.toList());
List<Integer> list = new ArrayList<Integer>() {{ add(1); add(2); add(3); }};

...unless we are happy to upgrade to Java 9 or add a dependency to one of the util libraries above or create a class extending ArrayList and writing our own constructor.


Finally, the question I ask: What reason made designers omit this constructor?

You can argue me that there already exists a constructor ArrayList(int initialCapacity) which "constructs an empty list with the specified initial capacity" (source at the same page) - I am aware this conflicts my idea, but honestly: how many times we had to declare the size of ArrayList in advance? Don't we need an ArrayList with predefined values used for ex. unit tests data? Isn't enough to initialize new ArrayList<>() which calls this(10) by default for 99,9% of cases?

Each List::add(..) calls a method that ensures the size of the array storing the values which are expensive for the huge amount of data and the constructor of ArrayList with a predefined size is welcome - so, why don't we use an array? Do we need to edit the large array afterward? - add it to the ArrayList using Arrays.asList(array) which calls System.arraycopy just once, or we can ensureCapacity.

This is how I understand the current design of ArrayList after browsing through some of the classes in java.util. Please, correct me where my understanding is wrong or knowledge insufficient.

Is there any technical issue explaining why constructor new ArrayList<>(1, 2, 3) was not realized?

Stuart Marks
  • 127,867
  • 37
  • 205
  • 259
Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
  • I don't see why the initial capacity parameter would conflict with a varargs initializer. – shmosel Mar 16 '18 at 22:48
  • 5
    shmosel: new ArrayList<>(1), where 1 is int - would it be a size of the list or the first element? – Nikolas Charalambidis Mar 16 '18 at 22:50
  • I see your point. – shmosel Mar 16 '18 at 22:51
  • @NikolasCharalambidis: It wouldn't conflict at all. Java's smart enough to determine which parameter to use from that alone. – Makoto Mar 16 '18 at 22:52
  • 2
    @Makoto I don't think it is. – Sam Orozco Mar 16 '18 at 22:52
  • 3
    @Makoto I can't even tell. How would Java know? – shmosel Mar 16 '18 at 22:53
  • @Aominè It *would* conflict, and your suggestion proves it. – user207421 Mar 16 '18 at 22:55
  • @EJP Right, true! – Ousmane D. Mar 16 '18 at 22:56
  • @Aominè: [You're not forced at all.](https://repl.it/repls/DarkturquoiseBlueBetaversion) – Makoto Mar 16 '18 at 22:57
  • It seems like you're actually asking why `initialCapacity` is necessary/useful, which is really a [separate question](https://stackoverflow.com/questions/15430247/why-start-an-arraylist-with-an-initial-capacity). – shmosel Mar 16 '18 at 22:58
  • @Makoto my point is doing `new ArrayList<>(1)` would always pick the non varargs constructor overload which in this case would be constructing an ArrayList with a capacity rather than an ArrayList with a single element. so assuming the user of this API really wanted an ArrayList with a single element and there was a varargs overload then you're _forced_ to help the compiler pick the varargs version by using the array syntax. – Ousmane D. Mar 16 '18 at 23:04
  • Furthermore, `new ArrayList<>(1, 2)` would be considered ambiguous. – shmosel Mar 16 '18 at 23:07

1 Answers1

7

ArrayList existed in Java 1.2. Varargs were a feature introduced in Java 1.5 (along with a whole heap of other features).

All of the features you really require from a vararg initialization of a list can be realized in Arrays.asList, which had to have existed around or after Java 1.5 due to its use of varargs.

Makoto
  • 104,088
  • 27
  • 192
  • 230