Convert Set to List without creating new List

1,010,945

Solution 1

You can use the List.addAll() method. It accepts a Collection as an argument, and your set is a Collection.

List<String> mainList = new ArrayList<String>();
mainList.addAll(set);

EDIT: as respond to the edit of the question.
It is easy to see that if you want to have a Map with Lists as values, in order to have k different values, you need to create k different lists.
Thus: You cannot avoid creating these lists at all, the lists will have to be created.

Possible work around:
Declare your Map as a Map<String,Set> or Map<String,Collection> instead, and just insert your set.

Solution 2

Use constructor to convert it:

List<?> list = new ArrayList<>(set);

Solution 3

Also from Guava Collect library, you can use newArrayList(Collection):

Lists.newArrayList([your_set])

This would be very similar to the previous answer from amit, except that you do not need to declare (or instanciate) any list object.

Solution 4

We can use following one liner in Java 8:

List<String> list = set.stream().collect(Collectors.toList());

Here is one small example:

public static void main(String[] args) {
        Set<String> set = new TreeSet<>();
        set.add("A");
        set.add("B");
        set.add("C");
        List<String> list = set.stream().collect(Collectors.toList());
}

Solution 5

the simplest solution

I wanted a very quick way to convert my set to List and return it, so in one line I did

 return new ArrayList<Long>(mySetVariable);
Share:
1,010,945
Muhammad Imran Tariq
Author by

Muhammad Imran Tariq

I am a passionate Senior Software Engineer. Majorly work in Java and BigData. I completed my masters degree in computer science and since then I developed various business application on different domains including financial systems, digitalsignage, security etc. I am also a good web developer and worked on different websites such as blogs, shopping carts. I have good understanding of programming languages and software development pros and cons.

Updated on April 11, 2022

Comments

  • Muhammad Imran Tariq
    Muhammad Imran Tariq about 2 years

    I am using this code to convert a Set to a List:

    Map<String, List<String>> mainMap = new HashMap<>();
    
    for (int i=0; i < something.size(); i++) {
      Set<String> set = getSet(...); //returns different result each time
      List<String> listOfNames = new ArrayList<>(set);
      mainMap.put(differentKeyName, listOfNames);
    }
    

    I want to avoid creating a new list in each iteration of the loop. Is that possible?

    • Muhammad Imran Tariq
      Muhammad Imran Tariq over 12 years
      I know a way to convert set to list as in Q. I want to avoind creating new list each time in loop.
    • DagR
      DagR over 12 years
      Why can't you just add the set to mainList? Why do you need to convert the Set into a List?
    • Hiery Nomus
      Hiery Nomus over 12 years
      Is it your intention to create a List<List<?>>
    • user207421
      user207421 almost 8 years
      You can't. Your question embodies a contradiction in terms.
  • Muhammad Imran Tariq
    Muhammad Imran Tariq over 12 years
    sorry it was mainMap not list. see question
  • amit
    amit over 12 years
    @imrantariq: is differentKeyName changing every iteration? Do you actually want something.size() different possible values in your maps? It is easy to see that a map with k lists as values needs to create at least k lists.
  • amit
    amit over 12 years
    @imrantariq: and you want a different list for each key I assume?
  • amit
    amit over 12 years
    @imrantariq: What you are requesting is impossible. read my edit for more details.
  • Taylor
    Taylor almost 12 years
    You haven't avoided creating the list. This code is trivially similar to the sample in your question.
  • vsingh
    vsingh almost 11 years
    If you are using guava, this is handy
  • glen3b
    glen3b about 10 years
    Although you are not directly calling the constructor, this method still calls the ArrayList constructor.
  • Koray Tugay
    Koray Tugay almost 10 years
    If I do not declare a List, how can I use the List created?
  • chaiyachaiya
    chaiyachaiya almost 10 years
    @KorayTugay, well you extract Lists.newArrayList([your_set]) in a variable (local or global). E.g: List<Foo> fooList = Lists.newArrayList(setOfFoo) But your question is flawed. If you create a list it is at least implicitly declared (if not explicitly).
  • Koray Tugay
    Koray Tugay almost 10 years
    I was confused because in the answer you say: except that you do not need to declare any list object..
  • chaiyachaiya
    chaiyachaiya almost 10 years
    @KorayTugay, true :) . Let's just say "instanciate" or "create"
  • DavidS
    DavidS over 9 years
    Any guess as to why this made this method? It doesn't seem any better than new ArrayList<>([your_set]).
  • mapeters
    mapeters almost 8 years
    He specifically said he wants to avoid this.
  • user207421
    user207421 almost 8 years
    @mook Irrelevant, as his requirement is not implementable.
  • user207421
    user207421 almost 8 years
    But it doesn't answer your quezon, not that there is an answer.
  • mapeters
    mapeters almost 8 years
    @EJP then his answer needs to say that, instead of simply stating something the OP didn't ask for without any explanation.
  • w35l3y
    w35l3y almost 8 years
    It will return NullPointerException in case set is null.
  • Gubatron
    Gubatron over 7 years
    he's avoiding it, that constructor uses System.arrayCopy, which makes shallow copies, meaning, it only copies the references of the objects into the array that's used to create the list. If you compare both collections, you will see that they both contain references to the same objects.
  • Kire Haglin
    Kire Haglin over 7 years
    You could imagine a method that would wrap a set into a list, similar to how you can wrap a list into an immutable list with Collections.unmodifiableList. It would probably not be a good idea to have such an API, since the order may change on inserts, but still
  • Vandal
    Vandal over 7 years
    Can you expand or elaborate more on this?
  • rajadilipkolli
    rajadilipkolli over 7 years
    Corrected size because new Object[0] will hold only one element but new Object[set.size()] will hold all values
  • kbluue
    kbluue about 7 years
    This doesn't actually work on Android. Any reason why?
  • Artem Lukanin
    Artem Lukanin over 6 years
    Collections.list() creates a new ArrayList: public static <T> ArrayList<T> list(Enumeration<T> e) { ArrayList<T> l = new ArrayList<>(); while (e.hasMoreElements()) l.add(e.nextElement()); return l; }
  • rrhrg
    rrhrg about 6 years
    For readability it's not recommended. For example, IntelliJ suggests "new ArrayList<>(set)" and lists more than 20 similar code samples with can be replaced the same way.
  • Ben
    Ben over 5 years
    This is also what IntelliJ IDEA suggests instead of the streams api.
  • user1075613
    user1075613 over 4 years
    @basheer one-liner solution using the ArrayList constructor is simpler. I don't understand why this answer is so much upvoted
  • Lii
    Lii about 4 years
    This is actually the only answer that actually solves the stated problem in the question!
  • Lii
    Lii about 4 years
    You can implement this pretty easily by extending AbstractList
  • Gaurav
    Gaurav about 4 years
    exactly! @rrhrg which is better for performance if we use set.parallelStream()?
  • cdalxndr
    cdalxndr almost 4 years
    Collectors.toList() creates a new list in memory
  • cdalxndr
    cdalxndr almost 4 years
    Unfortunately List.copyOf still allocates a new zone of memory to store items.
  • cdalxndr
    cdalxndr almost 4 years
    Good answer because it doesn't require new memory allocation, as the OP requested.
  • cdalxndr
    cdalxndr almost 4 years
    Overcomplicated. Instead of using an incomplete implementation of List to prevent violation of ordered elements, the simplest answer is to use Collection interface that is a base interface for both List and Set.
  • cdalxndr
    cdalxndr almost 4 years
    Collections.enumeration is a view and doesn't allocate new memory, but Collections.list creates a new ArrayList and stores all items there, thus it's not what OP wanted.
  • beatngu13
    beatngu13 almost 4 years
    @cdalxndr yes, like 95 % of the other answers, which is why I added this for the sake of completeness. However, I‘m happy to add a disclaimer if you want to?
  • cdalxndr
    cdalxndr almost 4 years
    I've downvoted 95% of other answers because of this. Ofc this answer should include info that it doesn't answer the requirements of the OP's question.
  • beatngu13
    beatngu13 almost 4 years
    @cdalxndr fair enough, updated the answer accordingly. But when you insist on the OP's requirements, how comes you like/edit this answer? This doesn't address the conversion from Set to List, and it is not clear whether Collection is sufficient or if List features are indeed required.
  • beatngu13
    beatngu13 almost 4 years
    This doesn't address the conversion from Set to List as requested by the OP. Unfortunately, it is not clear whether Collection is sufficient or if List features are indeed required.
  • cdalxndr
    cdalxndr almost 4 years
    Set is unordered, so the conversion to List without adding any ordering (like sorting) is still unordered (ordered randomly) so the List class is not required and any of it's features (all List methods are ordered specific) are undefined on randomly ordered List. From the OP's code, no ordering is added, so List should not be used.
  • beatngu13
    beatngu13 almost 4 years
    @cdalxndr based on the provided snippet, you can't tell what kind of set implementation is retrieved via getSet(...), if it is actually sorted or not. It is also unclear what happens after the map has been created. Title says convert set to list without creating a new list. IMO if creating a new list violates a requirement, so does converting to a different type. Anyway, I think we can agree to disagree.
  • cdalxndr
    cdalxndr almost 4 years
    Note that worst case when there is a single large set to be converted to list, the memory complexity is O(n) (double the memory) required for copying. So it is not "negligible", as opposed to noop polymorphism or a "view wrapper".
  • Andreas Covidiot
    Andreas Covidiot over 3 years
    @DavidS: factory (look up the concept and advantages) style methods are generally more flexible and general, easier to write and handle. E.g. imagine you provide a null set in a variable and want to get a null list in this case.
  • Catalin Pirvu
    Catalin Pirvu almost 3 years
    Up to this day, I don't know how this comment got so many upvotes, especially when doing a simple thing, but with more complexity as the other comments pointed out. Also, it's creating a new list, what the author tried to avoid.
  • GhostCat
    GhostCat over 2 years
    And lets not even talk about the performance penalty for turning to streams in the first place, for such a simple thing.