Convert Set to List without creating new List

前端 未结 15 899
鱼传尺愫
鱼传尺愫 2020-12-07 06:43

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

Map> mainMap = new HashMap<>();

for (int i         


        
相关标签:
15条回答
  • 2020-12-07 07:20

    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.

    0 讨论(0)
  • 2020-12-07 07:21

    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);
    
    0 讨论(0)
  • 2020-12-07 07:23

    You convert Set to List without adding ordering information (like sorting) just to store it in the map.

    Because Set is unordered and no ordering information is added, List should not be used, as it will contain randomly ordered data and all it's methods that are related to ordered data will be ambiguous.

    You should use Collection interface instead, that accepts both Set and List in the map. This way, no additional memory is required as you use polymorphism instead of copying data.

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

    Disclaimer: my edit to a similar answer was rejected so I added my own answer with additional information

    0 讨论(0)
  • 2020-12-07 07:26

    Recently I found this:

    ArrayList<T> yourList = Collections.list(Collections.enumeration(yourSet<T>));
    
    0 讨论(0)
  • 2020-12-07 07:28

    For the sake of completeness...

    Say that you really do want to treat the Map values as Lists, but you want to avoid copying the Set into a List each time.

    For instance, maybe you are calling one library function that creates a Set, but you are passing your Map<String, List<String>> result to a (poorly-designed but out of your hands) library function that only takes Map<String, List<String>>, even though somehow you know that the operations it does with the Lists are equally applicable to any Collection (and thus any Set). And for some reason you need to avoid the speed/memory overhead of copying each Set to a List.

    In this super niche case, depending on the (maybe unknowable) behavior the library function needs out of your Lists, you may be able to create a List view over each Set. Note that this is inherently unsafe (because the library function's requirements from each List could presumably change without you knowing), so another solution should be preferred. But here's how you'd do it.

    You'd create a class that implements the List interface, takes a Set in the constructor and assigns that Set to a field, and then uses that internal Set to implement the List API (to the extent possible, and desired).

    Note that some List behavior you simply will not be able to imitate without storing the elements as a List, and some behavior you will only partially be able to imitate. Again, this class is not a safe drop-in replacement for Lists in general. In particular, if you know that the use case requires index-related operations or MUTATING the List, this approach would go south very fast.

    public class ListViewOfSet<U> implements List<U> {
        private final Set<U> wrappedSet;
        public ListViewOfSet(Set<U> setToWrap) { this.wrappedSet = setToWrap; }
    
        @Override public int size() { return this.wrappedSet.size(); }
        @Override public boolean isEmpty() { return this.wrappedSet.isEmpty(); }
        @Override public boolean contains(Object o) { return this.wrappedSet.contains(o); }
        @Override public java.util.Iterator<U> iterator() { return this.wrappedSet.iterator(); }
        @Override public Object[] toArray() { return this.wrappedSet.toArray(); }
        @Override public <T> T[] toArray(T[] ts) { return this.wrappedSet.toArray(ts); }
        @Override public boolean add(U e) { return this.wrappedSet.add(e); }
        @Override public boolean remove(Object o) { return this.wrappedSet.remove(o); }
        @Override public boolean containsAll(Collection<?> clctn) { return this.wrappedSet.containsAll(clctn); }
        @Override public boolean addAll(Collection<? extends U> clctn) { return this.wrappedSet.addAll(clctn); }
        @Override public boolean addAll(int i, Collection<? extends U> clctn) { throw new UnsupportedOperationException(); }
        @Override public boolean removeAll(Collection<?> clctn) { return this.wrappedSet.removeAll(clctn); }
        @Override public boolean retainAll(Collection<?> clctn) { return this.wrappedSet.retainAll(clctn); }
        @Override public void clear() { this.wrappedSet.clear(); }
        @Override public U get(int i) { throw new UnsupportedOperationException(); }
        @Override public U set(int i, U e) { throw new UnsupportedOperationException(); }
        @Override public void add(int i, U e) { throw new UnsupportedOperationException(); }
        @Override public U remove(int i) { throw new UnsupportedOperationException(); }
        @Override public int indexOf(Object o) { throw new UnsupportedOperationException(); }
        @Override public int lastIndexOf(Object o) { throw new UnsupportedOperationException(); }
        @Override public ListIterator<U> listIterator() { throw new UnsupportedOperationException(); }
        @Override public ListIterator<U> listIterator(int i) { throw new UnsupportedOperationException(); }
        @Override public List<U> subList(int i, int i1) { throw new UnsupportedOperationException(); }
    }
    
    ...
    Set<String> set = getSet(...);
    ListViewOfSet<String> listOfNames = new ListViewOfSet<>(set);
    ...
    
    0 讨论(0)
  • 2020-12-07 07:30

    I create simple static method:

    public static <U> List<U> convertSetToList(Set<U> set)
    {
        return new ArrayList<U>(set);
    }
    

    ... or if you want to set type of List you can use:

    public static <U, L extends List<U>> List<U> convertSetToList(Set<U> set, Class<L> clazz) throws InstantiationException, IllegalAccessException
    {
        L list = clazz.newInstance();
        list.addAll(set);
        return list;
    }
    
    0 讨论(0)
提交回复
热议问题