java 将 Iterable<T> 转换为 T[] 的可重用方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6754554/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Reusable method to transform Iterable<T> to T[]?
提问by Dejas
I'm trying to write a generic method to return the contents of an Iterable in array form.
我正在尝试编写一个通用方法来以数组形式返回 Iterable 的内容。
Here is what I have:
这是我所拥有的:
public class IterableHelp
{
public <T> T[] toArray(Iterable<T> elements)
{
ArrayList<T> arrayElements = new ArrayList<T>();
for(T element : elements)
{
arrayElements.add(element);
}
return (T[])arrayElements.toArray();
}
}
But I'm getting a compiler warning 'Note: ...\IterableHelp.java uses unchecked or unsafe operations.'
但我收到编译器警告“注意:...\IterableHelp.java 使用未经检查或不安全的操作。”
Any thoughts on another approach that would avoid such a warning?
关于避免此类警告的另一种方法的任何想法?
回答by Daniel Pryden
There's a method Iterables.toArray
in Google Guava.
Iterables.toArray
谷歌番石榴中有一个方法。
Looking at the source, it's defined as:
查看源代码,它被定义为:
/**
* Copies an iterable's elements into an array.
*
* @param iterable the iterable to copy
* @param type the type of the elements
* @return a newly-allocated array into which all the elements of the iterable
* have been copied
*/
public static <T> T[] toArray(Iterable<? extends T> iterable, Class<T> type) {
Collection<? extends T> collection = toCollection(iterable);
T[] array = ObjectArrays.newArray(type, collection.size());
return collection.toArray(array);
}
Where ObjectArrays.newArray
eventually delegates to a method that looks like:
凡ObjectArrays.newArray
最终委托给方法的样子:
/**
* Returns a new array of the given length with the specified component type.
*
* @param type the component type
* @param length the length of the new array
*/
@SuppressWarnings("unchecked")
static <T> T[] newArray(Class<T> type, int length) {
return (T[]) Array.newInstance(type, length);
}
So it looks like there's no way to avoid the @SuppressWarnings
entirely, but you can and should at least constrain it to the smallest possible scope.
所以看起来没有办法@SuppressWarnings
完全避免,但是您可以并且至少应该将其限制在尽可能小的范围内。
Or, better yet, just use somebody else's implementation!
或者,更好的是,只需使用其他人的实现!
回答by Dejas
There isn't a way to get rid of the unchecked or unsafe operations
warning, or creating a TypeSafe Array without editing your method signature.
没有办法在unchecked or unsafe operations
不编辑方法签名的情况下消除警告或创建 TypeSafe 数组。
See this bug reportfor the gory details.
有关血腥的详细信息,请参阅此错误报告。
One way is to pass in a pre-allocated Array of Type T
:
一种方法是传入预先分配的 Type 数组T
:
public class IterableHelp
{
public <T> T[] toArray(final T[] t, final Iterable<T> elements)
{
int i = 0;
for (final T element : elements)
{
t[i] = element;
}
return t;
}
}
This gets rid of the unchecked or unsafe
warning, but it also puts the onus on the calling class to create the array with the correct bounds to begin with which kind of defeats the purpose of your convenience method.
这消除了unchecked or unsafe
警告,但它也让调用类有责任创建具有正确边界的数组,以哪种方式违背了您的便利方法的目的。
If you want to dynamically create a TypeSafe array, you really can't do it in a TypeSafe way in Java.
如果你想动态创建一个TypeSafe数组,在Java中用TypeSafe的方式确实是做不到的。
This works and compiles, but it doesn't solve the unchecked or unsafecast issue, it just moves it to a different place. I had to add the @SuppressWarnings
annotation to get it to stop complaining about the cast.
这有效并编译,但它不能解决未经检查或不安全的强制转换问题,它只是将其移动到不同的地方。我必须添加@SuppressWarnings
注释才能让它停止抱怨演员表。
@SuppressWarnings({"unchecked"})
public class IterableHelp
{
public <T> T[] toArray(Class<T> t, Iterable<T> elements)
{
final ArrayList<T> arrayElements = new ArrayList<T>();
for (T element : elements)
{
arrayElements.add(element);
}
final T[] ta = (T[]) Array.newInstance(t, arrayElements.size());
return arrayElements.toArray(ta);
}
}
回答by newacct
You got a bigger problem than the unchecked warning. In fact, it will throw a ClassCastException at runtime if T is anything other than Object.
您遇到了比未经检查的警告更大的问题。事实上,如果 T 不是 Object,它将在运行时抛出 ClassCastException。
Try String[] foo = IterableHelp.toArray(new ArrayList<String>());
尝试 String[] foo = IterableHelp.toArray(new ArrayList<String>());
Simply put, since arrays contain the component type at runtime, to create a proper T[] you must pass in the component class as another argument (either as the class of T or T[] itself, or as an object of T or T[]), and use reflection to create the array. The form of Collection
's toArray()
method that takes an argument, takes in a T[] object for this reason.
简单地说,由于数组在运行时包含组件类型,要创建一个合适的 T[],您必须将组件类作为另一个参数(作为 T 或 T[] 本身的类,或者作为 T 或 T 的对象) []),并使用反射创建数组。由于这个原因,接受参数Collection
的 的toArray()
方法的形式接受一个 T[] 对象。