0

I came across newArrayListWithCapacity(int) (1) in the codebase and was wondering if it has any advantages.

From what I understand, if we don't know the size, new ArrayList is going to serve the purpose, and if we do now the exact size, we can simply use an array. I'm trying to understand the benefits of using newArrayListWithCapacity(int). And how is it different from newArrayListWithExpectedSize?

If I define the expected size as x and if I end up having y number of entries, does it adversely affect the performance?

1: https://guava.dev/releases/15.0/api/docs/com/google/common/collect/Lists.html#newArrayListWithCapacity(int)

@GwtCompatible(serializable=true) public static ArrayList newArrayListWithCapacity(int initialArraySize) Creates an ArrayList instance backed by an array of the exact size specified; equivalent to ArrayList.ArrayList(int). Note: if you know the exact size your list will be, consider using a fixed-size list (Arrays.asList(Object[])) or an ImmutableList instead of a growable ArrayList.

Note: If you have only an estimate of the eventual size of the list, consider padding this estimate by a suitable amount, or simply use newArrayListWithExpectedSize(int) instead.

S.Dan
  • 1,826
  • 5
  • 28
  • 55
  • If you have an estimate of the size, then this is better than just creating an ArrayList. Have you read the Javadoc? – tgdavies Jul 28 '22 at 00:41
  • 4
    Anyway internally `newArrayListWithCapacity(int initialArraySize)` simply returns `new ArrayList(initialArraySize);` so your question is about difference between `new ArrayList(initialCapacity)` vs `new ArrayList()`; – Pshemo Jul 28 '22 at 00:56
  • 2
    Possibly related: [Why start an ArrayList with an initial capacity?](https://stackoverflow.com/q/15430247) – Pshemo Jul 28 '22 at 00:58
  • If x < y then the list needs to be expanded one or more times. If x > y then some heap is being used unnecesarily. – tgdavies Jul 28 '22 at 00:59
  • 1
    "if we do know the exact size, we can simply use an array" usually yes, but sometimes we can't. Sometimes we may want to use some method which accept only *List of elements* but not *array of elements* (and that method may want to modify such list so we can't use `Arrays.asList(array)` as it doesn't let us remove elements). In such cases when we are forced to use list we can improve performance of list by avoiding resizing its initial array. We simply need to provide initial size big enough to store all elements, but not greater than needed since we also don't want to take unnecessary memory. – Pshemo Jul 28 '22 at 01:02
  • 1
    You should try to find the latest documentation, rather than a very old version of it. https://guava.dev/releases/31.1-jre/api/docs/com/google/common/collect/Lists.html#newArrayListWithCapacity(int) says that both of those methods should be treated as deprecated. Use `new ArrayList(int capacity)` instead. – Klitos Kyriacou Jul 28 '22 at 08:44

1 Answers1

2

The method and the constructor do the same thing, which is to provide an ArrayList with a specific capacity, meaning that the initial backing array is created with the provided size.

Guava created a factory method wrapping the ArrayList(int) constructor because, while well documented, it might sometimes lead people in confusion. The Guava team did the same with other collection factory methods such as Sets.newHashSetWithCapacity(int) and Sets.newHashSetWithExpectedSize(int).

The pros are the following:

  • You have an explicit factory method name. This is good because not everyone knows what the constructors mean. So having a factory method that says what it creates is handy for people not entirely familiar with the API, but who are reading the code.
  • You don't have to handle generics in any way. Those are handled automatically for you through the generic method mechanism. Guava added this method in when Java 6 was released, so you had to manually add <FullTypeName> to each constructor calls (such as List<String> strings = new ArrayList<String>(10)). Nowadays you can simply use <> (such as List<String> strings = new ArrayList<>(10), but at the time the gain was huge!

The cons are:

  • You lose one method call of performance. But usually, when you're already dealing with Java's standard API, performance is not what you're looking for. Some other libraries provide high performance collections, and neither the Java Collections or Guava's Collections are serious contenders there. Also, as MikeFHay mentions in the comments below, the method call will likely be inlined in modern JVMs.
  • You depend of Google Guava. This is not really a letdown because Guava is a fantastic library, but if this is the only reason you use Guava, it might be.

The Guava team made that method because the pros clearly outmatch the cons in their view (which i personally share).

Olivier Grégoire
  • 33,839
  • 23
  • 96
  • 137