我在android环境下工作,并尝试了以下代码,但似乎不工作。
String [] stockArr = (String[]) stock_list.toArray();
如果我定义如下:
String [] stockArr = {"hello", "world"};
它的工作原理。我是不是遗漏了什么?
我在android环境下工作,并尝试了以下代码,但似乎不工作。
String [] stockArr = (String[]) stock_list.toArray();
如果我定义如下:
String [] stockArr = {"hello", "world"};
它的工作原理。我是不是遗漏了什么?
当前回答
正确的做法是:
String[] stockArr = stock_list.toArray(new String[stock_list.size()]);
我想在这里补充其他精彩的答案,并解释如何使用Javadocs来回答您的问题。
Javadoc for toArray()(无参数)在这里。如你所见,这个方法返回Object[]而不是String[], String[]是你的列表的运行时类型的数组:
public Object[] toArray() Returns an array containing all of the elements in this collection. If the collection makes any guarantees as to what order its elements are returned by its iterator, this method must return the elements in the same order. The returned array will be "safe" in that no references to it are maintained by the collection. (In other words, this method must allocate a new array even if the collection is backed by an Array). The caller is thus free to modify the returned array.
不过,在该方法的正下方是Javadoc for toArray(T[] a)。可以看到,该方法返回T[],其中T是传入的数组的类型。起初,这似乎是您正在寻找的东西,但不清楚为什么要传递一个数组(您是添加到数组中,还是仅用于类型等)。文档清楚地表明,传递数组的目的本质上是定义要返回的数组类型(这正是您的用例):
public <T> T[] toArray(T[] a) Returns an array containing all of the elements in this collection; the runtime type of the returned array is that of the specified array. If the collection fits in the specified array, it is returned therein. Otherwise, a new array is allocated with the runtime type of the specified array and the size of this collection. If the collection fits in the specified array with room to spare (i.e., the array has more elements than the collection), the element in the array immediately following the end of the collection is set to null. This is useful in determining the length of the collection only if the caller knows that the collection does not contain any null elements.) If this collection makes any guarantees as to what order its elements are returned by its iterator, this method must return the elements in the same order. This implementation checks if the array is large enough to contain the collection; if not, it allocates a new array of the correct size and type (using reflection). Then, it iterates over the collection, storing each object reference in the next consecutive element of the array, starting with element 0. If the array is larger than the collection, a null is stored in the first location after the end of the collection.
当然,要真正理解这两种方法之间的区别,需要理解泛型(如其他答案所述)。不过,如果您首先使用Javadocs,通常会找到答案,然后自己看看还需要学习什么(如果确实需要学习的话)。
还要注意,阅读这里的Javadocs有助于理解传入的数组的结构应该是什么。虽然它实际上可能并不重要,但你不应该像这样传入一个空数组:
String [] stockArr = stockList.toArray(new String[0]);
因为,从文档中,这个实现检查数组是否足够大以包含集合;如果不是,它分配一个正确大小和类型的新数组(使用反射)。当您可以轻松地传递数组大小时,就不需要在创建新数组时增加额外的开销。
与通常情况一样,Javadocs为您提供了丰富的信息和指导。
嘿,等一下,什么是反射?
其他回答
试试这个
String[] arr = list.toArray(new String[list.size()]);
像这样使用。
List<String> stockList = new ArrayList<String>();
stockList.add("stock1");
stockList.add("stock2");
String[] stockArr = new String[stockList.size()];
stockArr = stockList.toArray(stockArr);
for(String s : stockArr)
System.out.println(s);
Java 8中的替代方案:
String[] strings = list.stream().toArray(String[]::new);
发生的事情是stock_list.toArray()创建的是Object[]而不是String[],因此类型转换失败1。
正确的代码应该是:
String [] stockArr = stockList.toArray(new String[stockList.size()]);
甚至
String [] stockArr = stockList.toArray(new String[0]);
有关更多细节,请参考javadocs中List.toArray的两个重载。
后一个版本使用零长度数组来确定结果数组的类型。(令人惊讶的是,这样做比预先分配要快…至少对于最近的Java版本来说是这样的。详情见https://stackoverflow.com/a/4042464/139985。)
从技术角度来看,这种API行为/设计的原因是List<T>. toarray()方法的实现在运行时没有关于<T>是什么的信息。它只知道原始元素类型是Object。相反,在另一种情况下,数组形参给出数组的基类型。(如果提供的数组足够大,可以容纳列表元素,则使用它。否则,将分配一个相同类型且更大的新数组,并作为结果返回。)
1 -在Java中,Object[]与String[]不兼容。如果是,那么你可以这样做:
Object[] objects = new Object[]{new Cat("fluffy")};
Dog[] dogs = (Dog[]) objects;
Dog d = dogs[0]; // Huh???
这显然是毫无意义的,这就是数组类型通常不兼容赋值的原因。
正确的做法是:
String[] stockArr = stock_list.toArray(new String[stock_list.size()]);
我想在这里补充其他精彩的答案,并解释如何使用Javadocs来回答您的问题。
Javadoc for toArray()(无参数)在这里。如你所见,这个方法返回Object[]而不是String[], String[]是你的列表的运行时类型的数组:
public Object[] toArray() Returns an array containing all of the elements in this collection. If the collection makes any guarantees as to what order its elements are returned by its iterator, this method must return the elements in the same order. The returned array will be "safe" in that no references to it are maintained by the collection. (In other words, this method must allocate a new array even if the collection is backed by an Array). The caller is thus free to modify the returned array.
不过,在该方法的正下方是Javadoc for toArray(T[] a)。可以看到,该方法返回T[],其中T是传入的数组的类型。起初,这似乎是您正在寻找的东西,但不清楚为什么要传递一个数组(您是添加到数组中,还是仅用于类型等)。文档清楚地表明,传递数组的目的本质上是定义要返回的数组类型(这正是您的用例):
public <T> T[] toArray(T[] a) Returns an array containing all of the elements in this collection; the runtime type of the returned array is that of the specified array. If the collection fits in the specified array, it is returned therein. Otherwise, a new array is allocated with the runtime type of the specified array and the size of this collection. If the collection fits in the specified array with room to spare (i.e., the array has more elements than the collection), the element in the array immediately following the end of the collection is set to null. This is useful in determining the length of the collection only if the caller knows that the collection does not contain any null elements.) If this collection makes any guarantees as to what order its elements are returned by its iterator, this method must return the elements in the same order. This implementation checks if the array is large enough to contain the collection; if not, it allocates a new array of the correct size and type (using reflection). Then, it iterates over the collection, storing each object reference in the next consecutive element of the array, starting with element 0. If the array is larger than the collection, a null is stored in the first location after the end of the collection.
当然,要真正理解这两种方法之间的区别,需要理解泛型(如其他答案所述)。不过,如果您首先使用Javadocs,通常会找到答案,然后自己看看还需要学习什么(如果确实需要学习的话)。
还要注意,阅读这里的Javadocs有助于理解传入的数组的结构应该是什么。虽然它实际上可能并不重要,但你不应该像这样传入一个空数组:
String [] stockArr = stockList.toArray(new String[0]);
因为,从文档中,这个实现检查数组是否足够大以包含集合;如果不是,它分配一个正确大小和类型的新数组(使用反射)。当您可以轻松地传递数组大小时,就不需要在创建新数组时增加额外的开销。
与通常情况一样,Javadocs为您提供了丰富的信息和指导。
嘿,等一下,什么是反射?