Java Collections.nCopies Method
Last modified: April 20, 2025
The Collections.nCopies
method is a utility method in Java's
Collections Framework. It creates an immutable list containing multiple copies
of a single element. This is useful when you need a list with repeated values.
The method returns a list that contains n
copies of the specified
object. The list is immutable, meaning its size and elements cannot be changed.
All elements in the list reference the same object.
Collections.nCopies Overview
The nCopies
method is part of the java.util.Collections
class. It's a static factory method that creates a special kind of List
implementation. The returned list is space-efficient as it stores only one
element reference.
The method signature is: static <T> List<T> nCopies(int n, T o)
.
The first parameter is the number of copies, the second is the element to repeat.
The list is serializable and implements RandomAccess for efficient access.
Basic nCopies Example
This example demonstrates the simplest use of nCopies
. We create
a list containing five copies of the string "Hello". The resulting list is
immutable and cannot be modified.
package com.zetcode; import java.util.Collections; import java.util.List; public class BasicNCopies { public static void main(String[] args) { List<String> greetings = Collections.nCopies(5, "Hello"); System.out.println("List size: " + greetings.size()); System.out.println("List contents: " + greetings); try { greetings.add("Hi"); // Will throw exception } catch (UnsupportedOperationException e) { System.out.println("\nCannot modify nCopies list: " + e); } } }
This code creates an immutable list with five "Hello" strings. The list's size
is fixed at creation time. Attempting to modify the list throws an
UnsupportedOperationException
.
The output shows the list contents and demonstrates its immutability. This is useful for creating constant lists or default value collections.
Creating Initialized Lists
nCopies
can be used to initialize mutable lists. By passing the
immutable list to a constructor, we create a mutable copy. This is more
efficient than adding elements in a loop.
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class InitializeList { public static void main(String[] args) { // Create immutable list with 10 zeros List<Integer> immutableZeros = Collections.nCopies(10, 0); // Create mutable list from immutable one List<Integer> mutableZeros = new ArrayList<>(immutableZeros); System.out.println("Initial list: " + mutableZeros); // Now we can modify it mutableZeros.set(5, 99); mutableZeros.add(100); System.out.println("Modified list: " + mutableZeros); } }
This example shows how to use nCopies
for list initialization.
We first create an immutable list of zeros, then use it to construct a mutable
ArrayList
. The mutable list can then be modified as needed.
This approach is more efficient than using loops for initialization, especially for large lists. It clearly expresses the intent to create a list with default values.
Working with Custom Objects
nCopies
works with any object type, including custom classes. All
elements in the resulting list will reference the same object instance. This is
important to understand when working with mutable objects.
package com.zetcode; import java.util.Collections; import java.util.List; class Person { private String name; public Person(String name) { this.name = name; } public void setName(String name) { this.name = name; } @Override public String toString() { return name; } } public class CustomObjects { public static void main(String[] args) { Person original = new Person("John"); List<Person> people = Collections.nCopies(3, original); System.out.println("Original list: " + people); // Modify the original object original.setName("Jane"); System.out.println("After modification: " + people); } }
This example demonstrates nCopies
with a custom Person
class. The list contains multiple references to the same Person
object. Changing the original object affects all elements in the list.
This behavior is important to understand when working with mutable objects. For immutable objects (like Strings), this sharing is safe and memory-efficient.
Using nCopies with Streams
Java 8 streams can work with nCopies
lists. Although the list is
immutable, we can process its elements with stream operations. This example
shows filtering and mapping operations.
package com.zetcode; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; public class NCopiesStreams { public static void main(String[] args) { List<Integer> numbers = Collections.nCopies(10, 5); System.out.println("Original list: " + numbers); // Process with stream List<Integer> processed = numbers.stream() .map(n -> n * 2) // Double each number .filter(n -> n > 5) // Filter numbers > 5 .collect(Collectors.toList()); System.out.println("Processed list: " + processed); } }
This example creates a list of ten fives using nCopies
, then
processes it with a stream. The stream operations double each number and filter
those greater than five. The result is a new mutable list.
Streams provide a powerful way to process nCopies
lists without
modifying them. This is useful for transformations and calculations on repeated
values.
Performance Considerations
nCopies
is highly memory-efficient for large lists. It stores only
one element reference regardless of list size. This example compares memory
usage between nCopies
and regular list creation.
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class PerformanceTest { public static void main(String[] args) { final int SIZE = 1_000_000; // Using nCopies long start = System.nanoTime(); List<String> nCopyList = Collections.nCopies(SIZE, "item"); long nCopyTime = System.nanoTime() - start; // Using ArrayList start = System.nanoTime(); List<String> arrayList = new ArrayList<>(SIZE); for (int i = 0; i < SIZE; i++) { arrayList.add("item"); } long arrayListTime = System.nanoTime() - start; System.out.println("nCopies creation time (ms): " + nCopyTime / 1_000_000); System.out.println("ArrayList creation time (ms): " + arrayListTime / 1_000_000); System.out.println("nCopies memory efficient: " + (nCopyList.size() == arrayList.size())); } }
This example demonstrates the performance benefits of nCopies
.
Creating a million-element list with nCopies
is much faster than
populating an ArrayList
manually. It's also more memory-efficient.
The output shows the time difference between the two approaches. For large,
read-only lists of identical elements, nCopies
is the better choice.
nCopies in Data Structures
nCopies
can be used to initialize more complex data structures.
This example shows creating a list of lists, where each sublist contains
repeated values. This pattern is useful for matrix initialization.
package com.zetcode; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class MatrixInitialization { public static void main(String[] args) { final int ROWS = 3; final int COLS = 4; final int INIT_VALUE = 0; // Create list of lists using nCopies List<List<Integer>> matrix = new ArrayList<>( Collections.nCopies(ROWS, new ArrayList<>(Collections.nCopies(COLS, INIT_VALUE)) ); System.out.println("Initial matrix:"); matrix.forEach(row -> System.out.println(row)); // Modify one element matrix.get(1).set(2, 99); System.out.println("\nModified matrix:"); matrix.forEach(row -> System.out.println(row)); } }
This example creates a 3x4 matrix initialized with zeros using nested
nCopies
. The outer list contains references to the same inner
list, so modifying one row affects all rows. This demonstrates both the power
and potential pitfalls of nCopies
.
For proper matrix initialization, you would need to create distinct inner lists. This example serves as a caution about shared references in nested structures.
Alternative to nCopies
Java 8 introduced Stream.generate
as an alternative to
nCopies
. This example compares both approaches for creating
lists with repeated elements. Each has different characteristics and use cases.
package com.zetcode; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; public class StreamAlternative { public static void main(String[] args) { // Using nCopies List<String> nCopyList = Collections.nCopies(5, "Java"); System.out.println("nCopies result: " + nCopyList); // Using Stream.generate List<String> streamList = Stream.generate(() -> "Java") .limit(5) .collect(Collectors.toList()); System.out.println("Stream result: " + streamList); // Performance comparison long start = System.nanoTime(); Collections.nCopies(1_000_000, "Java"); long nCopyTime = System.nanoTime() - start; start = System.nanoTime(); Stream.generate(() -> "Java").limit(1_000_000).collect(Collectors.toList()); long streamTime = System.nanoTime() - start; System.out.println("\nnCopies time (ms): " + nCopyTime / 1_000_000); System.out.println("Stream time (ms): " + streamTime / 1_000_000); } }
This example shows two ways to create lists with repeated elements.
nCopies
creates an immutable list more efficiently, while
Stream.generate
creates a mutable list with more flexibility.
The performance comparison shows nCopies
is faster for large
lists. However, streams offer more processing options if you need mutability
or transformations.
Source
Java Collections.nCopies Documentation
In this article, we've explored the Collections.nCopies
method in
depth. We've covered basic usage, performance characteristics, and alternatives.
This method is valuable for creating memory-efficient immutable lists of
repeated elements.
Author
List all Java tutorials.