如何从 List<> 转换 ArrayList<>
Posted
技术标签:
【中文标题】如何从 List<> 转换 ArrayList<>【英文标题】:How to cast ArrayList<> from List<> 【发布时间】:2011-02-27 16:50:06 【问题描述】:有人能解释一下为什么我不能用第一种方法将List<>
转换为ArrayList<>
而我用第二种方法吗?谢谢。
第一种方法:
ArrayList<Task> tmp = ((ArrayList<Task>)mTrackytAdapter.getAllTasks(token));
第二种方法:
ArrayList<Task> tmp = new ArrayList<Task>(mTrackytAdapter.getAllTasks(token));
【问题讨论】:
【参考方案1】:当你做第二个时,你是在创建一个新的数组列表,而不是试图假装另一个列表是一个数组列表。
我的意思是,如果原始列表被实现为链表或一些自定义列表怎么办?你不会知道的。如果您确实需要从结果中创建一个数组列表,则首选第二种方法。但是您可以将其保留为列表,这是使用接口的最大优势之一!
【讨论】:
【参考方案2】:当您使用第二种方法时,您正在使用其预定义值初始化 arraylist。 就像我们通常做的那样 ArrayList listofStrings = new ArrayList(); 假设您有一个包含值的数组,现在您想将此数组转换为 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 不是实际的数组列表,它只是一个不允许对列表进行任何修改的包装器。 如果您尝试在 Arrays.asList 上添加或删除,它会给您
UnsupportedOperationException
【讨论】:
【参考方案3】:尝试运行以下代码:
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
所以,这意味着它们是 2 个不相互扩展的不同类。 java.util.Arrays$ArrayList 表示名为 ArrayList 的私有类(Arrays 类的内部类),java.util.ArrayList 表示名为 ArrayList 的公共类。因此,从 java.util.Arrays$ArrayList 转换为 java.util.ArrayList 以及反之亦然是不相关的/不可用的。
【讨论】:
【参考方案4】:如果你想强制转换,第二种方法显然是错误的。它实例化一个新的 ArrayList。
但是,当且仅当 getAllTasks 返回一个 ArrayList 时,第一种方法应该可以正常工作。
你真的需要一个 ArrayList 吗?列表界面还不够吗?如果类型不正确,您正在执行的操作可能会导致运行时异常。
如果 getAllTasks() 返回一个 ArrayList,您应该更改类定义中的返回类型,然后您就不需要强制转换,如果它返回其他内容,则不能强制转换为 ArrayList。
【讨论】:
【参考方案5】:试试这个:
ArrayList<SomeClass> arrayList;
public SomeConstructor(List<SomeClass> listData)
arrayList.addAll(listData);
【讨论】:
【参考方案6】:如果您了解自己在做什么,您可以将 List 转换为 ArrayList。 Java 编译器不会阻塞它。
但是:
-
不检查就将父类型转换为子类型(或接口转换为实现类型)是不好的做法。
这样更好:
if (list instanceof ArrayList<Task>)
ArrayList<Task> arraylist = (ArrayList<Task>) list;
-
也许您不需要实现类型作为参考。看 SonarQube 警告https://sbforge.org/sonar/rules/show/squid:S1319。在大多数情况下,您可以避免这种强制转换。
您可以使用 Guava 方法:
ArrayList<Task> arraylist = Lists.newArrayList(list);
【讨论】:
【参考方案7】:第一种方法是尝试强制转换列表,但这只有在List<>
是ArrayList<>
时才有效。事实并非如此。所以你需要第二种方法,即用List<>
的元素构建一个新的ArrayList<>
【讨论】:
【参考方案8】:因为在第一个中,您正在尝试将集合转换为 ArrayList。 在第二个中,您只需使用built in constructor of ArrayList
【讨论】:
【参考方案9】:可能是:
ArrayList<ServiceModel> services = new ArrayList<>(parking.getServices());
intent.putExtra("servicios",services);
【讨论】:
【参考方案10】: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);
【讨论】:
以上是关于如何从 List<> 转换 ArrayList<>的主要内容,如果未能解决你的问题,请参考以下文章