Most concise way to convert a Set<T> to a List<T>

220,570

Solution 1

List<String> list = new ArrayList<String>(listOfTopicAuthors);

Solution 2

List<String> l = new ArrayList<String>(listOfTopicAuthors);

Solution 3

Considering that we have Set<String> stringSet we can use following:

Plain Java

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

Guava

List<String> strList = Lists.newArrayList(stringSet);

Apache Commons

List<String> strList = new ArrayList<>();
CollectionUtils.addAll(strList, stringSet);

Java 10 (Unmodifiable List)

List<String> strList = List.copyOf(stringSet);
List<String> strList = stringSet.stream().collect(Collectors.toUnmodifiableList());

Java 8 (Modifiable Lists)

import static java.util.stream.Collectors.*;
List<String> stringList1 = stringSet.stream().collect(toList());

As per the doc for the method toList()

There are no guarantees on the type, mutability, serializability, or thread-safety of the List returned; if more control over the returned List is required, use toCollection(Supplier).

So if we need a specific implementation e.g. ArrayList we can get it this way:

List<String> stringList2 = stringSet.stream().
                              collect(toCollection(ArrayList::new));

Java 8 (Unmodifiable Lists)

We can make use of Collections::unmodifiableList method and wrap the list returned in previous examples. We can also write our own custom method as:

class ImmutableCollector {
    public static <T> Collector<T, List<T>, List<T>> toImmutableList(Supplier<List<T>> supplier) {
            return Collector.of( supplier, List::add, (left, right) -> {
                        left.addAll(right);
                        return left;
                    }, Collections::unmodifiableList);
        }
}

And then use it as:

List<String> stringList3 = stringSet.stream()
             .collect(ImmutableCollector.toImmutableList(ArrayList::new)); 

Another possibility is to make use of collectingAndThen method which allows some final transformation to be done before returning result:

    List<String> stringList4 = stringSet.stream().collect(collectingAndThen(
      toCollection(ArrayList::new),Collections::unmodifiableList));

One point to note is that the method Collections::unmodifiableList returns an unmodifiable view of the specified list, as per doc. An unmodifiable view collection is a collection that is unmodifiable and is also a view onto a backing collection. Note that changes to the backing collection might still be possible, and if they occur, they are visible through the unmodifiable view. But the collector method Collectors.unmodifiableList returns truly immutable list in Java 10.

Solution 4

Try this for Set:

Set<String> listOfTopicAuthors = .....
List<String> setList = new ArrayList<String>(listOfTopicAuthors); 

Try this for Map:

Map<String, String> listOfTopicAuthors = .....
// List of values:
List<String> mapValueList = new ArrayList<String>(listOfTopicAuthors.values());
// List of keys:
List<String> mapKeyList = new ArrayList<String>(listOfTopicAuthors.KeySet());

Solution 5

If you are using Guava, you statically import newArrayList method from Lists class:

List<String> l = newArrayList(setOfAuthors);
Share:
220,570

Related videos on Youtube

Daniel
Author by

Daniel

aka Gavin

Updated on July 08, 2022

Comments

  • Daniel
    Daniel almost 2 years

    For example, I am currently doing this:

    Set<String> setOfTopicAuthors = ....
    
    List<String> list = Arrays.asList( 
        setOfTopicAuthors.toArray( new String[0] ) );
    

    Can you beat this ?

    • Tim
      Tim about 14 years
      Use java.util.Collection: O(0)
    • Daniel
      Daniel about 14 years
      @Carl, I have to submit the Set into a 3rd party interface which requires a List. @Tim I wish I could change the 3rd party interface to use Collection.
    • Carl
      Carl about 14 years
      I see; barring any strange constraints, I'd go with Roger's answer. Though, unless you actually use the List again, I'd skip assigning it to anything (i.e., use foo.api(new ArrayList<String>(listOfTopicAuthors)) instead of foo.api(list)).
    • realPK
      realPK about 7 years
      @JacquesRenéMesrine: First line of code in question is misleading: Expected: Set<String> setOfTopicAuthors = .... Actual: Set<String> listOfTopicAuthors = ....
    • Naman
      Naman almost 6 years
      Or an alternate way to do the same could be List<String> list = Arrays.asList(setOfTopicAuthors.toArray(String[]::new)), detailed in the linked answer.
    • akhil_mittal
      akhil_mittal over 5 years
      Java 8 and Java 10 solution : stackoverflow.com/a/32179585/1216775
  • Håvard Geithus
    Håvard Geithus over 10 years
    ... and thereby radically defying the Java code conventions: oracle.com/technetwork/java/javase/documentation/… ! :) :)
  • CoDe
    CoDe almost 10 years
    after this when I tried to access list element it giving me error, " java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String" ..don;t know why..it's simple list.get(int) that's it ...any suggestion ?
  • Brett Duncavage
    Brett Duncavage over 9 years
    I believe in Java 7 and above you can omit the type parameter to ArrayList yielding: List<String> l = new ArrayList<>(listOfTopicAuthors); Most concise without using an external library?
  • jayeffkay
    jayeffkay over 8 years
    for answering in the same minute as accepted answer and not getting the cred. +1
  • Ungeheuer
    Ungeheuer over 8 years
    I used this to convert a Set<Double> to a List<Double, where the set came from a LinkedHashMap's .keySet() method. Eclipse told me that there was a type mismatch, and that I could not convert from Object to List<Double>. Could you tell me why this may have happened? I got around it by casting, but I was wondering why it happens.
  • Jack
    Jack about 8 years
    @Adamski I end up with a list who's index begins at 1 instead of 0, any remedy?
  • Adamski
    Adamski about 8 years
    @Jack: That definitely won't be the case. From the Javadoc from java.util.List: "Lists (like Java arrays) are zero based."
  • Jack
    Jack about 8 years
    @Adamski Thanks for the response. I know lists should be and are zero based which is why this is so strange to me. After converting my set to a list I can't perform any iterative operation on it foreach, sort, etc. I get a NullPointerException, however when I expect my list none of the elements are null, and the only weird I notice is that the index starts at 1. However, if I just create a normal list the index starts at 0. Weird?
  • Adamski
    Adamski about 8 years
    @Jack: That sounds very weird. If you post your code as a separate question I'm sure someone will be able to help you out.
  • w35l3y
    w35l3y over 7 years
    It will throw NullPointerException in case listOfTopicAuthors is null.
  • Shubham Pandey
    Shubham Pandey over 6 years
    Yes, since Java Developers should be using more and more Java 8 features, this answer is better than the above 2 answers.