如何投射ArrayList<>来自List<>

时间:2011-02-27 16:50:07

标签: java generics casting

有人可以解释一下,为什么我不能用第一种方法将List<>投射到ArrayList<>而我用第二种做法?谢谢。

第一种方法:

ArrayList<Task> tmp = ((ArrayList<Task>)mTrackytAdapter.getAllTasks(token));

第二种方法:

ArrayList<Task> tmp = new ArrayList<Task>(mTrackytAdapter.getAllTasks(token));

10 个答案:

答案 0 :(得分:25)

当你做第二个时,你正在制作一个新的arraylist,你不是试图假装另一个列表是一个arraylist。

我的意思是,如果将原始列表实现为链接列表或某些自定义列表,该怎么办?你不会知道的。如果你真的需要从结果中创建一个arraylist,那么第二种方法是首选。但是您可以将其保留为列表,这是使用Interfaces的最佳优势之一!

答案 1 :(得分:11)

当您使用第二种方法时,您正在使用其预定义值初始化arraylist。 我们一般都喜欢 ArrayList listofStrings = new ArrayList&lt;&gt;(); 假设您有一个包含值的数组,现在您想将此数组转换为arraylist。

您需要首先使用Arrays utils从数组中获取列表。 因为ArrayList是实现List接口的具体类型。不能保证方法asList会返回这种类型的实现。

List<String>  listofOptions = (List<String>) Arrays.asList(options);

然后你可以使用arraylist的构造函数来实例化预定义的值。

ArrayList<String> arrlistofOptions = new ArrayList<String>(list);

所以你的第二种方法就是你已经传递了值,这些值将使用列表元素来实现arraylist。

更多

从Arrays.asList返回的ArrayList不是实际的arraylist,它只是一个包装器,它不允许在列表中进行任何修改。 如果您尝试添加或删除Arrays.asList,它将为您提供

  

UnsupportedOperationException异常

答案 2 :(得分:5)

如果你想要演员,第二种方法显然是错误的。它实例化一个新的ArrayList。

然而,第一种方法应该可以正常工作,当且仅当getAllTask​​s返回一个ArrayList时。

你真的需要一个ArrayList吗? List接口不够用吗?如果类型不正确,您正在做的事情会导致运行时异常。

如果getAllTask​​s()返回一个ArrayList,你应该更改类定义中的返回类型,然后你不需要强制转换,如果它返回别的东西,你就不能转换为ArrayList。

答案 3 :(得分:4)

试试这个:

ArrayList<SomeClass> arrayList;

 public SomeConstructor(List<SomeClass> listData) {
        arrayList.addAll(listData);
}

答案 4 :(得分:2)

你可以投射List&lt;&gt;到ArrayList&lt;&gt;如果你明白你在做什么。 Java编译器不会阻止它。

可是:

  1. 将父类型转换为子类型(或实现类型的接口)而不进行检查是不好的做法。 这样更好:
  2. if (list instanceof ArrayList<Task>) { ArrayList<Task> arraylist = (ArrayList<Task>) list; }

    1. 也许您不需要实现类型作为参考。查看SonarQube警告https://sbforge.org/sonar/rules/show/squid:S1319。在大多数情况下,你可以避免这种演员。
    2. 您可以使用番石榴方法: ArrayList<Task> arraylist = Lists.newArrayList(list);

答案 5 :(得分:1)

第一种方法是尝试投射列表,但这仅在List<>ArrayList<>时才有效。事实并非如此。因此,您需要第二种方法,即使用ArrayList<>

的元素构建新的List<>

答案 6 :(得分:1)

因为在第一个中,您正在尝试将集合转换为ArrayList。 在第二个中,您只需使用built in constructor of ArrayList

答案 7 :(得分:1)

尝试运行以下代码:

List<String> listOfString = Arrays.asList("Hello", "World");
ArrayList<String> arrayListOfString = new ArrayList(listOfString);
System.out.println(listOfString.getClass());
System.out.println(arrayListOfString.getClass());

您将获得以下结果:

class java.util.Arrays$ArrayList
class java.util.ArrayList

因此,这意味着他们有两个不相互延伸的不同类别。 java.util.Arrays $ ArrayList表示名为ArrayList的私有类(Arrays类的内部类),java.util.ArrayList表示名为ArrayList的公共类。因此,从java.util.Arrays $ ArrayList到java.util.ArrayList的反转是相互关联的/不可用的。

答案 8 :(得分:0)

可能是:

ArrayList<ServiceModel> services = new ArrayList<>(parking.getServices());
intent.putExtra("servicios",services);

答案 9 :(得分:0)

import java.util.List;
import java.util.Arrays;
import java.util.*;

public class Merge
{  
  public static void main(String[] args) {
  // This is normal way
  // List<Integer> l1 = new ArrayList<Integer>(); l1.add(2); l1.add(5); l1.add(10); l1.add(22); 
  // List<Integer> l2 = new ArrayList<Integer>(); l2.add(3); l2.add(8); l2.add(15); 

 //Array.asList only have the list interface, but ArrayList is inherited from List Interface with few more property like ArrayList.remove()
 List<Integer> templ1 = Arrays.asList(2,5,10,22); 
 List<Integer> templ2 =  Arrays.asList(3,8,12);
//So creation of ArrayList with the given list is required, then only ArrayList.remove function works. 
 List<Integer> l1 = new ArrayList<Integer>(templ1);
 List<Integer> l2 = new ArrayList<Integer>(templ2);
 List<Integer> l3 = new ArrayList<Integer>();

 Iterator itr1 = l1.iterator();
 while(itr1.hasNext()){
    int x = (Integer) itr1.next();
    Iterator itr2 = l2.iterator();
    while(itr2.hasNext()) {
      int y = (Integer) itr2.next(); 
      if(x < y) {
        l3.add(x);
        break;
      }
      else{
        l3.add(y);
        itr2.remove();
         
      }
    }
 }
 
 Iterator it = l1.iterator(); 
 while (it.hasNext()){
  int k = (Integer) it.next();
  if (l3.contains(k)){
     continue;
  }
  else{
     l3.add(k);
     System.out.println(k);
  }
 }
 
 Iterator itr2 = l2.iterator();
 while (itr2.hasNext()){
  int k = (Integer) itr2.next();
  l3.add(k);
 }
 
 System.out.println(l3);
 }
}