【问题标题】:Arrays.asList: when a set is used as the argument we get back a list<set<Integer>> instead of List<Integer>Arrays.asList:当一个集合用作参数时,我们得到一个 list<set<Integer>> 而不是 List<Integer>
【发布时间】:2020-05-07 05:11:33
【问题描述】:
Set<Integer> iset = new HashSet<>();
iset.add(1);
List<Integer> ilist =  Arrays.asList(iset);

我的意图是将整数集转换为整数列表,但编译器抱怨无法将 List> 转换为 List。为什么 asList 会以这种方式工作,什么时候会使用它?将 Set 转换为 List 的正确方法是什么?

【问题讨论】:

  • List&lt;Integer&gt; ilist = new ArrayList&lt;&gt;(iset);
  • 您执行 asList(oneX),然后您会得到一个 OneX 列表……该集合对象没有自动“解包”!

标签: java generics collections


【解决方案1】:

因为Arrays.asList 仅将iset 视为一个元素。这就是创建 List&lt;Set&lt;Integer&gt;&gt; 的原因。

要创建集合中元素的列表,请将集合传递给列表的构造函数。

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

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 

【讨论】:

  • 所以该方法的正常用法是为其提供多个参数?
  • Arrays.asList 的正常用法是为其提供一个事物数组,这可以表示单个thing[] 参数或多个thing 参数。无论哪种方式,您都会收到List&lt;thing&gt;
  • 您可以同时使用数组或单个元素
  • 这叫做 varargs
【解决方案2】:

我希望以下示例可以帮助您理解为什么会发生这种情况。

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

    }

}

【讨论】:

    【解决方案3】:

    Arrays.asList 接收一个 varargs 参数,这是一个隐藏的数组。

    它只是返回一个包含数组参数元素的List 对象。

    所以,如果你这样做:

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

    你会得到一个包含[1, 2, 3]List&lt;Integer&gt;

    如果你有这个泛型类:

    class MyObject<T> { }
    

    然后做:

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

    你会得到一个包含[myStrObj1, myStrObj2]List&lt;MyObject&lt;String&gt;&gt;

    当您将Set&lt;Integer&gt; 的某些实例传递给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);
    

    你会得到一个包含[[1], [5, 6]]List&lt;Set&lt;Integers&gt;&gt;


    如果您只想创建一个新的List 对象,其元素与Set 对象相同,则必须迭代该集合并将其每个元素添加到列表中:

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

    幸运的是,ArrayList 的构造函数正是为您完成了这项工作。所以你所要做的就是:

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

    【讨论】:

      猜你喜欢
      • 2014-05-04
      • 2018-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-22
      • 2014-02-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多