Alb*_*ert 7 java collections types casting toarray
现在,我有:
public <T> T[] toArray(T[] old) {
T[] arr = Arrays.copyOf(old, old.length + size());
int i = old.length;
for(E obj : this) {
arr[i] = old.getClass().getComponentType().cast(obj);
++i;
}
return arr;
}
Run Code Online (Sandbox Code Playgroud)
(请注意,这不符合合同,因为axtavt指出了这一点.)
在哪里我得到这个警告:
Type safety: Unchecked cast from capture#2-of ? to T
Run Code Online (Sandbox Code Playgroud)
这仍然是实现它的最佳/最直接的方法吗?我可以以某种方式编码它而没有那个警告吗?我将如何实施呢?
编辑:我目前的解决方案.首先,我真的希望自己不要有这样的警告toArray.因此,我编写了这些小辅助函数(请在此处阅读以进一步讨论这些函数):
@SuppressWarnings("unchecked") static <T> Class<? extends T> classOf(T obj) {
return (Class<? extends T>) obj.getClass();
}
@SuppressWarnings("unchecked") static <T> Class<? extends T> classOf(T[] array) {
return (Class<? extends T>) array.getClass().getComponentType();
}
@SuppressWarnings("unchecked") static <T> T[] newArray(Class<T> clazz, int size) {
return (T[]) Array.newInstance(clazz, size);
}
Run Code Online (Sandbox Code Playgroud)
现在,我的toArray实现看起来像:
public <T> T[] toArray(T[] array) {
int size = size();
if (array.length < size) {
array = newArray(classOf(array), size);
} else if (array.length > size) {
array[size] = null;
}
int i = 0;
for (E e : this) {
array[i] = classOf(array).cast(e);
i++;
}
return array;
}
Run Code Online (Sandbox Code Playgroud)
这仍然是实现它的最佳/最直接的方法吗?我将如何实施呢?
这不是Josh Bloch的表现.看看源头AbstractCollection#toArray().以下是JDK 1.6.0_22的相关摘录.
public <T> T[] toArray(T[] a) {
// Estimate size of array; be prepared to see more or fewer elements
int size = size();
T[] r = a.length >= size
? a
: (T[]) Array.newInstance(a.getClass().getComponentType(), size);
Iterator<E> it = iterator();
for (int i = 0; i < r.length; i++) {
if (!it.hasNext()) { // fewer elements than expected
if (a != r)
return Arrays.copyOf(r, i);
r[i] = null; // null-terminate
return r;
}
r[i] = (T) it.next();
}
return it.hasNext() ? finishToArray(r, it) : r;
}
Run Code Online (Sandbox Code Playgroud)
源代码src.zip在JDK的文件中可用.您可以将它集成到Eclipse/IDEA/Netbeans等任何体面的IDE中,以便在打开AbstractCollection课程时可以看到它.
我可以以某种方式编码它而没有那个警告吗?
不,@SuppressWarnings("unchecked")如果它困扰你,请使用.
也就是说,如果可能的话,我建议扩展AbstractCollection而不是实现Collection,这样你至少已经为你实现了基本功能.
首先,如果它应该是一个实现Collection.toArray(),它不遵循合同 - 你不应该在数组中保留旧元素(请参阅javadoc).
正确的实现如下所示:
public <T> T[] toArray(T[] array) {
int size = size();
if (array.length < size) {
// If array is too small, allocate the new one with the same component type
array = Array.newInstance(array.getClass().getComponentType(), size);
} else if (array.length > size) {
// If array is to large, set the first unassigned element to null
array[size] = null;
}
int i = 0;
for (E e: this) {
// No need for checked cast - ArrayStoreException will be thrown
// if types are incompatible, just as required
array[i] = (T) e;
i++;
}
return array;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5526 次 |
| 最近记录: |