1. Overview
In this tutorial, we’ll learn how to construct a list containing primitive integer values.
We’ll explore solutions using core Java and external libraries.
2. Autoboxing
In Java, generic type arguments must be reference types. This means we can’t do something like List<int>.
Instead, we can use List<Integer> and take advantage of autoboxing. Autoboxing helps us use the List<Integer> interface as if it contained primitive int values. Under the hood, it is still a collection of Objects and not primitives.
The core Java solution is just an adjustment to be able to use primitives with generic collections. Moreover, it comes with the cost of boxing and unboxing conversions.
However, there are other options in Java and additional third-party libraries that we can use. Let’s see how to use them below.
3. Using the Stream API
Oftentimes, we don’t actually need to create a list as much as we just need to operate on it.
In these cases, it might work to use Java 8’s Stream API instead of creating a list altogether. The IntSream class provides a sequence of primitive int elements that supports sequential aggregate operations.
Let’s have a quick look at an example:
IntStream stream = IntStream.of(5, 10, 0, 2, -8);
The IntStream.of() static method returns a sequential IntStream.
Similarly, we can create an IntStream from an existing array of ints:
int[] primitives = {5, 10, 0, 2, -8}; IntStream stream = IntStream.of(primitives);
Moreover, we can apply the standard Stream API operations to iterate, filter and aggregate the ints. For example, we can calculate the average of the positive int values:
OptionalDouble average = stream.filter(i -> i > 0).average();
Most importantly, no autoboxing is used while working with the streams.
Though, if we definitely need a concrete list, we’ll want to take a look at one of the following third-party libraries.
4. Using Trove
Trove is a high-performance library which provides primitive collections for Java.
To setup Trove with Maven, we need to include the trov4j dependency in our pom.xml:
<dependency> <groupId>net.sf.trove4j</groupId> <artifactId>trove4j</artifactId> <version>3.0.2</version> </dependency>
With Trove, we can create lists, maps, and sets.
For instance, there is an interface TIntList with its TIntArrayList implementation to work with a list of int values:
TIntList tList = new TIntArrayList();
Even though TIntList can’t directly implement List, it’s methods are very comparable. Other solutions that we discuss follow a similar pattern.
The greatest benefit of using TIntArrayList is performance and memory consumption gains. No additional boxing/unboxing is needed as it stores the data inside of an int[] array.
5. Using Fastutil
Another high-performance library to work with the primitives is Fastutil. Let’s add the fastutil dependency:
<dependency> <groupId>it.unimi.dsi</groupId> <artifactId>fastutil</artifactId> <version>8.1.0</version> </dependency>
Now, we’re ready to use it:
IntArrayList list = new IntArrayList();
The default constructor IntArrayList() internally creates an array of primitives with the default capacity of 16. In the same vein, we can initialize it from an existing array:
int[] primitives = new int[] {5, 10, 0, 2, -8}; IntArrayList list = new IntArrayList(primitives);
6. Using Colt
Colt is an open source, a high-performance library for scientific and technical computing. The cern.colt package contains resizable lists holding primitive data types such as int.
First, let’s add the colt dependency:
<dependency> <groupId>colt</groupId> <artifactId>colt</artifactId> <version>1.2.0</version> </dependency>
The primitive list that offers this library is cern.colt.list.IntArrayList:
cern.colt.list.IntArrayList coltList = new cern.colt.list.IntArrayList();
The default initial capacity is ten.
7. Using Guava
Guava provides a number of ways of interfacing between primitive arrays and collection APIs. The com.google.common.primitives package has all the classes to accommodate primitive types.
For example, the ImmutableIntArray class lets us create an immutable list of int elements.
Let’s suppose, we have the following array of int values:
int[] primitives = new int[] {5, 10, 0, 2};
We can simply create a list with the array:
ImmutableIntArray list = ImmutableIntArray.builder().addAll(primitives).build();
Furthermore, it provides a list API with all the standard methods we would expect.
8. Conclusion
In this quick article, we showed multiple ways of creating lists with the primitive integers. In our examples, we used the Trove, Fastutil, Colt, and Guava libraries.
As usual, the complete code for this article is available over on GitHub.