Memory conscious toList collector with Java 8

The following code:

    List source = Arrays.asList(1, 2, 3, 4, 5);
    List result = new ArrayList<> (source.size());
    for (int i : source) result.add(2 * i);

can easily be transformed to use lambdas in Java 8, for example:

    List result =
                                 .map(i -> 2 * i)

There is however an important difference: in the first code, the result list has a capacity of 5, whereas in the second code it has a capacity of 10, hence using more memory*.

The Collectors utility class also offers a toCollection method which accepts a Supplier<Collection>. That method allows to use a properly sized collection, for example:

    Supplier s = () -> new ArrayList<>(source.size());
    List result =
                                 .map(i -> 2 * i)

The code is now equivalent to the original code without lambdas and the result list has an optimal capacity.

*The capacity of the backing array can easily be checked with:

    Field f = ArrayList.class.getDeclaredField("elementData");
    System.out.println(((Object[]) f.get(result)).length);

Tagged , , ,

One thought on “Memory conscious toList collector with Java 8

  1. Derek Peirce says:

    Note that this only works if your end stream is guaranteed to be the same size as your initial collection, which changes whenever you introduce filters or flat mappings.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: