Convert Set to List without creating new List

2019-01-15 23:34发布

问题:

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

Map<String, List> mainMap = new HashMap<String, List>();

for(int i=0; i<something.size(); i++){
  Set set = getSet(...); //returns different result each time
  List 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?

回答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.



回答2:

Use constructor to convert it:

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


回答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.



回答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());
}


回答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);


回答6:

You could use this one line change: Arrays.asList(set.toArray(new Object[set.size()]))

Map<String, List> mainMap = new HashMap<String, List>();

for(int i=0; i<something.size(); i++){
  Set set = getSet(...); 
  mainMap.put(differentKeyName, Arrays.asList(set.toArray(new Object[set.size()])));
}  


回答7:

I would do :

Map<String, Collection> mainMap = new HashMap<String, Collection>();

for(int i=0; i<something.size(); i++){
  Set set = getSet(...); //return different result each time
  mainMap.put(differentKeyName,set);
}


回答8:

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;
}


回答9:

Java 8 provides the option of using streams and you can get a list from Set<String> setString as:

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

Though the internal implementation as of now provides an instance of ArrayList:

public static <T>
    Collector<T, ?, List<T>> toList() {
        return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
                                   (left, right) -> { left.addAll(right); return left; },
                                   CH_ID);
    }

but JDK does not guarantee it. As mentioned here:

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).

In case you want to be sure always then you can request for an instance specifically as:

List<String> stringArrayList = setString.stream()
                     .collect(Collectors.toCollection(ArrayList::new));


回答10:

Recently I found this:

ArrayList<T> yourList = Collections.list(Collections.enumeration(yourSet<T>));


回答11:

I found this working fine and useful to create a List from a Set.

ArrayList < String > L1 = new ArrayList < String > ();
L1.addAll(ActualMap.keySet());
for (String x: L1) {
    System.out.println(x.toString());
}


回答12:

Map<String, List> mainMap = new HashMap<String, List>();

for(int i=0; i<something.size(); i++){
  Set set = getSet(...); //return different result each time
  mainMap.put(differentKeyName, new ArrayList(set));
}