我有一个难题,使我不得不思考是否有任何标准的Java类在Iterable<T>
没有实现的情况下也实现了Collection<T>
。我正在实现一个接口,要求我定义一个接受的方法Iterable<T>
,但是我用来支持该方法的对象需要一个Collection<T>
。
这让我做了一些真正的浮躁感觉代码,在编译时会发出一些未经检查的警告。
public ImmutableMap<Integer, Optional<Site>> loadAll(
Iterable<? extends Integer> keys
) throws Exception {
Collection<Integer> _keys;
if (keys instanceof Collection) {
_keys = (Collection<Integer>) keys;
} else {
_keys = Lists.newArrayList(keys);
}
final List<Site> sitesById = siteDBDao.getSitesById(_keys);
// snip: convert the list to a map
将我的结果集合更改为使用更通用的Collection<? extends Integer>
类型并不能消除该行的未经检查的警告。另外,我不能将方法签名更改为接受a Collection
而不是an,Iterable
因为那样它就不再覆盖super方法,并且在需要时不会被调用。
目前似乎没有被周围的方式该铸造或拷贝的问题:其他问题已经问这里的其他地方似乎深深扎根于Java的泛型和类型擦除系统。但是我想问的是,是否有可以实现Iterable<T>
但又不实现的类Collection<T>
?我已经看过Iterable
JavaDoc,当然,我希望传递给接口的所有内容实际上都是一个集合。我想使用一个狂野的,预先编写的类,因为这似乎更有可能实际作为参数传递,并使单元测试的价值更大。
由于我正在编写一些单元测试,我敢肯定我写的转换或复制位与我在项目中使用的类型兼容。但我想编写一个单元测试的一些输入端,是一个可迭代但不是一个集合,到目前为止,所有我已经能够拿出正在实施一个虚拟的测试类实现自己。
出于好奇,我正在实现的方法是Guava的CacheLoader<K, V>.loadAll(Iterable<? extends K> keys)
方法,后备方法是JDBI实例化的数据访问对象,该方法要求将集合用作@BindIn
接口的参数类型。我认为这与问题是相切的,我是正确的,但以防万一有人想尝试对我的问题进行横向思考。我知道我可以派生JDBI项目并重写@BindIn
注释以接受可迭代的...
在阅读了出色的答案并提供了文档之后,我又翻了几节课,发现无论从测试代码的直接性还是直接的问题标题来看,看起来都是赢家。Java的主要ArrayList
实现包含以下gem:
public Iterator<E> iterator() {
return new Itr();
}
Itr
私有内部类在哪里,其中包含的高度优化的定制实现Iterator<E>
。不幸的是,Iterator
它本身并没有实现Iterable
,所以如果我想把它塞进我的助手方法中以测试不进行强制转换的代码路径,则必须将其包装在自己的实现Iterable
(而不是实现Collection
)的垃圾类中,返回Itr
。这是一种方便的方法,可以轻松地将集合变成Iterable,而不必自己编写迭代代码。
最后一点,我的最终版本代码甚至都没有进行强制转换,因为Guava Lists.newArrayList
几乎完全按照问题中的运行时类型检测进行了操作。
@GwtCompatible(serializable = true)
public static <E> ArrayList<E> More ...newArrayList(Iterable<? extends E> elements) {
checkNotNull(elements); // for GWT
// Let ArrayList's sizing logic work, if possible
if (elements instanceof Collection) {
@SuppressWarnings("unchecked")
Collection<? extends E> collection = (Collection<? extends E>) elements;
return new ArrayList<E>(collection);
} else {
return newArrayList(elements.iterator());
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句