Arrays.asList: when a set is used as the argument we get back a list<set<Integer>> instead of List<Integer>

Viewed 811
Set<Integer> iset = new HashSet<>();
iset.add(1);
List<Integer> ilist =  Arrays.asList(iset);

My intention was to convert the set of integers into a list of integers but the compiler complains that a List> cannot be converted to a List. Why does asList work this way and when would one use it? What is the correct way to convert a Set to List?

3 Answers

Because Arrays.asList treats iset as only one element. That's why this creates List<Set<Integer>>.

To make a list of the elements in a set, pass the set to the constructor of the list.

List<Integer> ilist = new ArrayList<Integer>(iset);

Different uses of Arrays.asList:

List<Integer> ilist1 = Arrays.asList(1); // Single element
List<Integer> ilist2 = Arrays.asList(1,2,3); // Multiple element
Integer a[] = new Integer[] { 10, 20, 30, 40 }; 
List<Integer> ilist3 = Arrays.asList(a); // Array 

I hope the following example can help you to understand why this is happening.

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.HashSet;

public class practice {

    public static void main(String... string) {


        /**
         *  This will return a list of Integer, because if we see the implementation of Arrays.asList() 
         *  then this all puzzle will be solved.
         *  Arrays can process a Array collection of data.
         *  asList is generic implementation, returned object data type will be same as received dataType                     
         */
        Integer a[] = new Integer[] {1, 2, 3, 4};
        List<Integer> arrList =  Arrays.asList(a);


        /**
         * But in this case, Arrays.asList() is receiving a collection of Integer object and asList will try to return the 
         * same type of data as it received.
         * So it received Set and will return set 
         * and for more investigation apply debug points in ArrayList class under java.util.Arrays.ArrayList  
         */
        Set<Integer> iset = new HashSet<>();
        iset.add(1);
        List<Set<Integer>> ilist =  Arrays.asList(iset);

    }

}

Arrays.asList receives a varargs argument, which is an array under the covers.

It simply returns a List object that contains the elements of the array argument.

So, if you do:

List<Integer> numbers = Arrays.asList(1, 2, 3);

You get a List<Integer> containing [1, 2, 3].

If you have this generic class:

class MyObject<T> { }

And do:

MyObject<String> myStrObj1 = new MyObject<>();
MyObject<String> myStrObj2 = new MyObject<>();

List<MyObject<String>> myStrObjects = Arrays.asList(myStrObj1, myStrObj2);

You get a List<MyObject<String>> containing [myStrObj1, myStrObj2].

The same happens when you pass some instances of Set<Integer> to Arrays.asList:

Set<Integer> integerSet1 = new HashSet<>();
integerSet1.add(1);

Set<Integer> integerSet2 = new HashSet<>();
integerSet2.add(5);
integerSet2.add(6);

List<Set<Integer>> integerSets =  Arrays.asList(integerSet1, integerSet2);

You get a List<Set<Integers>> containing [[1], [5, 6]].


If you just want to create a new List object with the same elements as the Set object, you have to iterate the set and add each one of its elements to the list:

Set<Integer> set = new HashSet<>();
set.add(1);
set.add(2);
set.add(3);

List<Integer> list = new ArrayList<>();

for (Integer element : set) {
    list.add(element);
}

Luckily, the constructor of ArrayList does exactly this for you. So all you have to do is:

Set<Integer> set = new HashSet<>();
set.add(1);
set.add(2);
set.add(3);

List<Integer> list = new ArrayList<>(set);
Related