Tutorial

How to Convert a Set to a List in Java: Simple and Efficient Methods

Updated on April 21, 2025
authorauthor

By Jayant Verma and Anish Singh Walia

How to Convert a Set to a List in Java: Simple and Efficient Methods

Lists in Java are ordered collection of data, whereas sets are an unordered collection of data. A list can have duplicate entries, a set can not. Both the data structures are useful in different scenarios.

Knowing how to convert a set into a list is useful. It can convert unordered data into ordered data.

Initializing a set

Let’s initialize a set and add some elements to it.

import java.util.*;

public class Main {

    public static void main(String[] args)
    {
        Set<Integer> a = new HashSet<>();
        a.add(1);
        a.add(2);
        a.add(3);
        a.add(1);
        System.out.println(a);
    }
}

Set

The add() method of HashSet adds the elements to the set. Note that the elements are distinct. There is no way to get the elements according to their insertion order as the sets are unordered.

Converting Set to List in Java

Let’s convert the set into a list. There are multiple ways of doing so. Each way is different from the other and these differences are subtle.

1. List Constructor with Set argument

The most straightforward way to convert a set to a list is by passing the set as an argument while creating the list. This calls the constructor and from there onwards the constructor takes care of the rest.

import java.util.*;

public class Main {

    public static void main(String[] args)
    {
        Set<Integer> a = new HashSet<>();
        a.add(1);
        a.add(2);
        a.add(3);
        a.add(1);

     List<Integer> arr = new ArrayList<>(a);
     System.out.println(arr);
     System.out.println(arr.get(1));

    }
}
Using Constructor
Output

Since the set has been converted to a list, the elements are now ordered. That means we can use the get() method to access elements by index.

2. Using conventional for loop

We can use the good old for loop to explicitly copy the elements from the set to the list.

import java.util.*;

public class Main {

    public static void main(String[] args)
    {
        Set<Integer> a = new HashSet<>();
        a.add(1);
        a.add(2);
        a.add(3);
        a.add(1);

     List<Integer> arr = new ArrayList<>(a);
        for (int i : a)
            arr.add(i);
        System.out.println(arr);
        System.out.println(arr.get(1));
    }   
}

Using for-loop

For loop goes over the set element by element and adds the elements to the list.

3. List addAll() method

Lists have a method called addAll() that adds multiple values to the list at once. You might recall this operation from its use in merging two lists. addAll() also works for adding the elements of a set to a list.

import java.util.*;

public class Main {

    public static void main(String[] args)
    {
        Set<Integer> a = new HashSet<>();
        a.add(1);
        a.add(2);
        a.add(3);
        a.add(1);

     List<Integer> arr = new ArrayList<>();
        arr.addAll(a);
        System.out.println(arr);
        System.out.println(arr.get(1));
    }
}

Using addAll()

4. Stream API collect() method

Stream.collect() is available from Java 8 onwards. ToList collector collects all Stream elements into a List instance.

import java.util.*;
import java.util.stream.Collectors;


public class Main {

    public static void main(String[] args)
    {
        Set<Integer> a = new HashSet<>();
        a.add(1);
        a.add(2);
        a.add(3);
        a.add(1);

     List<Integer> arr;

        arr = a.stream().collect(Collectors.toList());
        System.out.println(arr);
        System.out.println(arr.get(1));
    }
}

using stream.collect()

The documentation for stream.collect() mentions that there is no guarantee on the type, mutability, serializability, or thread-safety of the List returned. If more control over the returned List is required, use toCollection(Supplier).

To specify the type of list use toCollection(ArrayList::new)

import java.util.*;
import java.util.stream.Collectors;


public class Main {

    public static void main(String[] args)
    {
        Set<Integer> a = new HashSet<>();
        a.add(1);
        a.add(2);
        a.add(3);
        a.add(1);

     List<Integer> arr;

  arr = a.stream().collect(Collectors.toCollection(ArrayList::new));
        System.out.println(arr);
        System.out.println(arr.get(1));
    }
}

Recommended Reading: Streams in Java

5. List.copyOf() method

Java 10 onwards List has a copyOf() method. The method returns an unmodifiable List containing the elements of the given Collection, in its iteration order. The list can’t contain any null elements. In case the set contains ‘null’, the method returns a null pointer exception.

import java.util.*;
import java.util.stream.Collectors;


public class Main {

    public static void main(String[] args)
    {
        Set<Integer> a = new HashSet<>();
        a.add(1);
        a.add(2);
        a.add(3);
        a.add(1);

     List<Integer> arr;

        arr = List.copyOf(a);
        System.out.println(arr);
        System.out.println(arr.get(1));
    }
}

using List.copyOf()

Adding a null in the set and trying to convert to a list :

import java.util.*;
import java.util.stream.Collectors;

public class Main {

    public static void main(String[] args)
    {
        Set<Integer> a = new HashSet<>();
        a.add(1);
        a.add(2);
        a.add(3);
        a.add(1);
        a.add(null);

     List<Integer> arr;

        arr = List.copyOf(a);
        System.out.println(arr);
        System.out.println(arr.get(1));
    }
}
Null Pointer Exception
Null Pointer Exception

If you try to add an element to an immutable list you’ll get an error that looks like the following.

Immutable Error
Immutable Error

Using the addAll() method to convert set with null element to a list :

import java.util.*;
import java.util.stream.Collectors;


public class Main {

    public static void main(String[] args)
    {
        Set<Integer> a = new HashSet<>();
        a.add(1);
        a.add(2);
        a.add(3);
        a.add(1);
        a.add(null);

     List<Integer> arr = new ArrayList<>();
     arr.addAll(a);

      //  arr = List.copyOf(a);
        System.out.println(arr);
        System.out.println(arr.get(1));
    }
}

AddAll() with Null

Note that the null appears at the beginning of the list.

Practical Use Cases

1. Reordering a Set for indexed access

When working with sets, elements are not stored in a specific order. However, in certain scenarios, it’s essential to access elements by their index. Converting a set to a list allows for indexed access, making it easier to manipulate or process elements in a specific order.

For example, consider a set of unique user IDs. To process these IDs in a specific order (e.g., alphabetical or numerical), converting the set to a list and then sorting the list would be an effective approach.

Set<String> userIds = new HashSet<>();
userIds.add("user1");
userIds.add("user2");
userIds.add("user3");

List<String> orderedUserIds = new ArrayList<>(userIds);
Collections.sort(orderedUserIds);

// Now, orderedUserIds can be accessed by index for processing

2. Converting unique inputs to lists for batch operations

Sets are ideal for storing unique elements, but they are not suitable for batch operations that require processing elements in a specific order. Converting a set to a list enables batch processing, ensuring that each element is processed exactly once and in a predictable order.

For instance, consider a set of unique product IDs that need to be processed in batches for inventory management. By converting the set to a list, you can ensure that each product ID is processed in a specific order, such as by product category or alphabetical order.

Set<String> productIds = new HashSet<>();
productIds.add("product1");
productIds.add("product2");
productIds.add("product3");

List<String> orderedProductIds = new ArrayList<>(productIds);
// Assuming there's a method to process products in batches
processProductsInBatches(orderedProductIds);

3. Sorting a Set after conversion to a List

Sets do not maintain a specific order of elements, which can be a limitation in certain scenarios. By converting a set to a list, you can sort the elements based on specific criteria, such as alphabetical or numerical order.

For example, consider a set of strings that represent names. To sort these names alphabetically, converting the set to a list and then sorting the list would be an effective approach.

Set<String> names = new HashSet<>();
names.add("John");
names.add("Alice");
names.add("Bob");

List<String> sortedNames = new ArrayList<>(names);
Collections.sort(sortedNames);

// Now, sortedNames contains the names in alphabetical order

4. Working with NLP token sets and preserving insertion order for analysis

In Natural Language Processing (NLP), token sets are often used to represent unique words or tokens in a text. When analyzing these tokens, preserving the insertion order can be crucial for understanding the context and meaning of the text. Converting a set of tokens to a list allows for the preservation of insertion order, enabling more accurate analysis.

For instance, consider a set of unique words extracted from a text. To analyze the frequency of these words or their co-occurrence patterns, converting the set to a list and preserving the insertion order can be beneficial.

Set<String> uniqueWords = new HashSet<>();
uniqueWords.add("word1");
uniqueWords.add("word2");
uniqueWords.add("word3");

List<String> orderedUniqueWords = new ArrayList<>(uniqueWords);
// Now, orderedUniqueWords can be analyzed while preserving the insertion order

Understanding the Difference between Mutable and Immutable Lists after Conversion

When converting a set to a list, it’s essential to understand the implications of the conversion method on the resulting list’s mutability. Mutability refers to the ability to modify the list after its creation. In Java, lists can be either mutable or immutable, each with its own characteristics and use cases.

Mutable Lists

A mutable list is a list that can be modified after its creation. This means elements can be added, removed, or modified within the list. Most commonly used list implementations in Java, such as ArrayList, are mutable. When converting a set to a list using methods like the constructor or addAll(), the resulting list is mutable. This allows for dynamic changes to the list as needed.

For example, consider the following code snippet that converts a set to a mutable list using the constructor:

Set<String> names = new HashSet<>();
names.add("John");
names.add("Alice");
names.add("Bob");

List<String> mutableNamesList = new ArrayList<>(names);
// Now, mutableNamesList is a mutable list that can be modified

Immutable Lists

An immutable list, on the other hand, is a list that cannot be modified after its creation. Once created, the elements within the list cannot be changed. In Java, List.copyOf() method produces an immutable list. This method is particularly useful when you need to ensure that the list remains unchanged after its creation.

For instance, consider the following code snippet that converts a set to an immutable list using List.copyOf():

Set<String> names = new HashSet<>();
names.add("John");
names.add("Alice");
names.add("Bob");

List<String> immutableNamesList = List.copyOf(new ArrayList<>(names));
// Now, immutableNamesList is an immutable list that cannot be modified

Key Takeaways

When converting a set to a list, it’s crucial to consider the mutability requirements of your application. If you need to dynamically modify the list, a mutable list is suitable. However, if you require a list that remains unchanged after creation, an immutable list is the better choice. Understanding the differences between mutable and immutable lists ensures that you make informed decisions about the type of list to use in your Java applications.

Common Errors and Debugging

1. Loss of insertion order if using HashSet

When using a HashSet to store elements, the insertion order is not preserved. This is because HashSet does not maintain the order of elements. To fix this, you can use a LinkedHashSet which preserves the insertion order.

Set<String> orderedSet = new LinkedHashSet<>();
orderedSet.add("word1");
orderedSet.add("word2");
orderedSet.add("word3");

List<String> orderedUniqueWords = new ArrayList<>(orderedSet);
// Now, orderedUniqueWords preserves the insertion order

2. Confusion when converting Set<String> vs Set<Object>

When converting a Set to a List, it’s essential to ensure that the type parameters match. If the Set is of type String, the List should also be of type String. Mixing types can lead to confusion and errors.

Set<String> stringSet = new HashSet<>();
stringSet.add("John");
stringSet.add("Alice");
stringSet.add("Bob");

// Correct conversion
List<String> stringList = new ArrayList<>(stringSet);

// Incorrect conversion (mixing types)
// List<Object> objectList = new ArrayList<>(stringSet); // Avoid this

3. Duplicates when modifying sets/lists during iteration

Modifying a set or list during iteration can lead to unexpected behavior, including duplicates. To avoid this, create a temporary collection to hold the modified elements, and then update the original collection.

Set<String> names = new HashSet<>();
names.add("John");
names.add("Alice");
names.add("Bob");

// Create a temporary list to hold modified elements
List<String> modifiedNames = new ArrayList<>();
for (String name : names) {
    modifiedNames.add(name + " modified");
}

// Update the original set with the modified elements
names.clear();
names.addAll(modifiedNames);

4. UnsupportedOperationException when trying to modify an unmodifiable list

When trying to modify an unmodifiable list, a UnsupportedOperationException is thrown. This occurs when using methods like List.copyOf() or Collections.unmodifiableList(). To fix this, ensure that you’re not trying to modify an unmodifiable list.

List<String> unmodifiableList = List.copyOf(new ArrayList<>(names));
// Attempting to modify an unmodifiable list will throw an exception
// unmodifiableList.add("New Name"); // This will throw an exception

// To modify the list, use a mutable list
List<String> mutableList = new ArrayList<>(names);
mutableList.add("New Name"); // This is allowed

FAQs

1. How do you convert a Set to a List in Java?

Converting a Set to a List in Java can be done using various methods. One common approach is to use the ArrayList constructor and pass the Set as an argument. Here’s an example:

Set<String> stringSet = new HashSet<>();
stringSet.add("John");
stringSet.add("Alice");
stringSet.add("Bob");

List<String> stringList = new ArrayList<>(stringSet);

Another approach is to use Java 8’s Stream API to convert the Set to a List:

List<String> stringList = stringSet.stream()
                                 .collect(Collectors.toList());

2. What is the difference between a Set and a List in Java?

A Set in Java is an unordered collection of unique elements, meaning it does not allow duplicates. A List, on the other hand, is an ordered collection that can contain duplicates. Here’s a simple example to illustrate the difference:

Set<String> stringSet = new HashSet<>();
stringSet.add("John");
stringSet.add("Alice");
stringSet.add("Bob");
stringSet.add("John"); // Duplicate, will not be added

List<String> stringList = new ArrayList<>();
stringList.add("John");
stringList.add("Alice");
stringList.add("Bob");
stringList.add("John"); // Duplicate, will be added

3. Which is faster: using a constructor or a stream for conversion?

The performance difference between using a constructor and a stream for converting a Set to a List is negligible for small to medium-sized collections. However, for large collections, using a constructor might be slightly faster since it avoids the overhead of creating a stream pipeline.

Here’s a simple benchmark to compare the two approaches:

Set<String> largeSet = new HashSet<>();
for (int i = 0; i < 1000000; i++) {
    largeSet.add("Element " + i);
}

long startTime = System.nanoTime();
List<String> listUsingConstructor = new ArrayList<>(largeSet);
long endTime = System.nanoTime();
System.out.println("Time taken using constructor: " + (endTime - startTime) + " ns");

startTime = System.nanoTime();
List<String> listUsingStream = largeSet.stream()
                                      .collect(Collectors.toList());
endTime = System.nanoTime();
System.out.println("Time taken using stream: " + (endTime - startTime) + " ns");

4. How to preserve insertion order when converting a Set to a List?

When converting a Set to a List, the order of elements is not guaranteed to be preserved. If you need to preserve the insertion order, you can use a LinkedHashSet instead of a HashSet for maintaining the order of elements based on their insertion order:

Set<String> orderedSet = new LinkedHashSet<>();
orderedSet.add("John");
orderedSet.add("Alice");
orderedSet.add("Bob");

List<String> orderedList = new ArrayList<>(orderedSet);

5. Can I convert a HashSet to an ArrayList?

Yes, you can convert a HashSet to an ArrayList. The process is similar to converting any Set to a List, as shown in the first FAQ. However, keep in mind that the order of elements in the resulting ArrayList will not be the same as the order in which elements were inserted into the HashSet.

Here’s an example:

HashSet<String> hashSet = new HashSet<>();
hashSet.add("John");
hashSet.add("Alice");
hashSet.add("Bob");

ArrayList<String> arrayList = new ArrayList<>(hashSet);

6. What happens to duplicates when converting from List to Set and back?

When converting a List to a Set, duplicates are removed because a Set cannot contain duplicate elements. If you convert the resulting Set back to a List, the duplicates will not be restored.

Here’s an example:

List<String> listWithDuplicates = new ArrayList<>();
listWithDuplicates.add("John");
listWithDuplicates.add("Alice");
listWithDuplicates.add("Bob");
listWithDuplicates.add("John"); // Duplicate

Set<String> setWithoutDuplicates = new HashSet<>(listWithDuplicates);
List<String> listWithoutDuplicates = new ArrayList<>(setWithoutDuplicates);

Conclusion

In this tutorial, we explored various methods to convert a Set to a List in Java, including using constructors, streams, and loops. We also discussed the importance of considering the type of list created by each method, such as the immutability of lists created by copyOf() and the unpredictability of stream.collect(). Additionally, we highlighted the reliability of using constructors and addAll() for conversion.

If you’re interested in learning more about working with lists in Java, we recommend checking out the following tutorials:

These tutorials will provide you with a deeper understanding of list operations and how to effectively utilize them in your Java applications.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the author(s)

Category:
Tutorial

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.