有没有任何Java标准类实现Iterable没有实现集合? [英] Are there any Java standard classes that implement Iterable without implementing Collection?

查看:417
本文介绍了有没有任何Java标准类实现Iterable没有实现集合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个难题,让我思考是否有任何标准的java类实现 Iterable< T> ,而没有实现 Collection< T> ; 。我实现一个接口,需要我定义一个接受 Iterable< T> 的方法,但是我用来回退这个方法的对象需要一个 Collection< T>

I have a conundrum that's caused me to ponder whether there are any standard java classes that implement Iterable<T> without also implementing Collection<T>. I'm implementing one interface that requires me to define a method that accepts an Iterable<T>, but the object I'm using to back this method requires a Collection<T>.

这让我做了一些真正的kludgy感觉代码,编译时提供一些未经检查的警告。 >

This has me doing some really kludgy feeling code that give some unchecked warnings when compiled.

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> 类型不会消除该行的未选中警告。此外,我不能改变方法签名接受集合而不是 Iterable ,因为它不再覆盖超级方法,并且在需要时不会调用。

Changing my resulting collection to use the more generified Collection<? extends Integer> type doesn't eliminate the unchecked warning for that line. Also, I can't change the method signature to accept a Collection instead of an Iterable because then it's no longer overriding the super method and won't get called when needed.

似乎不是绕过这个铸造或复制问题的方法:其他问题在这里被问到别处,它似乎根深蒂固的Java的通用和类型擦除系统。但我要求相反,如果有任何类可以实现 Iterable< T> ,也不实现集合< T& code>?我通过 可迭代 JavaDoc ,当然,我期望传递给我的界面的所有东西实际上都是一个集合。我想使用一个野生的,预先编写的类,因为这似乎更可能实际上作为一个参数传递,并使单元测试更有价值。

There doesn't seem to be a way around this cast-or-copy problem: other questions have been asked here an elsewhere and it seems deeply rooted in Java's generic and type erasure systems. But I'm asking instead if there ever are any classes that can implement Iterable<T> that don't also implement Collection<T>? I've taken a look through the Iterable JavaDoc and certainly everything I expect to be passed to my interface will actually be a collection. I'd like to use an in-the-wild, pre-written class instead as that seems much more likely to actually be passed as a parameter and would make the unit test that much more valuable.

我确定我写的cast-or-copy的位与我在我的项目中使用的类型,因为我正在写一些单元测试。但是我想为一些输入写一个单元测试,这些输入是是一个可迭代的,但不是的集合,到目前为止,我已经能够找到

I'm certain the cast-or-copy bit I've written works with the types I'm using it for in my project due to some unit tests I'm writing. But I'd like to write a unit test for some input that is an iterable yet isn't a collection and so far all I've been able to come up with is implementing a dummy-test class implementation myself.

对于好奇,我实现的方法是Guava的 CacheLoader< ; K,V> .loadAll(Iterable< ;? extends K> keys) ,并且支持方法是JDBI实例化的数据访问对象,其需要将集合用作参数键入 @BindIn 界面。我想我是正确的,认为这是切题的问题,但只是为了防止任何人想尝试横向思考我的问题。我知道我可以只分叉JDBI项目,并重写 @BindIn 注释接受一个迭代...

For the curious, the method I'm implementing is Guava's CacheLoader<K, V>.loadAll(Iterable<? extends K> keys) and the backing method is a JDBI instantiated data-access object, which requires a collection to be used as the parameter type for the @BindIn interface. I think I'm correct in thinking this is tangental to the question, but just in case anyone wants to try lateral thinking on my problem. I'm aware I could just fork the JDBI project and rewrite the @BindIn annotation to accept an iterable...

推荐答案

在阅读完优秀的答案和提供的文档后,我在几个课程中捅了一下,发现什么看起来是赢家,无论是直接测试代码还是直接问题标题。 Java的主要 ArrayList 实现包含此gem:

After reading the excellent answers and provided docs, I poked around in a few more classes and found what looks to be the winner, both in terms of straightforwardness for test code and for a direct question title. Java's main ArrayList implementation contains this gem:

public Iterator<E> iterator() {
    return new Itr();
}

其中 Itr 具有高度优化的自定义实现 Iterator< E> 的私有内部类。不幸的是, Iterator 本身并不实现 Iterable ,所以如果我想把它变成我的帮助方法测试代码路径不做转换,我必须将其包装在我自己的实现 Iterable (而不是集合)并返回 Itr 。这是一种方便的方法,可以轻松地将一个集合转换为Iterable,而不必自己编写迭代代码。

Where Itr is a private inner class with a highly optimized, customized implementation of Iterator<E>. Unfortunately, Iterator doesn't itself implement Iterable, so if I want to shoe horn it into my helper method for testing the code path that doesn't do the cast, I have to wrap it in my own junk class that implements Iterable (and not Collection) and returns the Itr. This is a handy way to easily to turn a collection into an Iterable without having to write the iteration code yourself.

最后一点,我的最终版本的代码doesn甚至做演员本身,因为Guava的 Lists.newArrayList 几乎完全是我的在问题中使用运行时类型检测。

On a final note, my final version of the code doesn't even do the cast itself, because Guava's Lists.newArrayList does pretty much exactly what I was doing with the runtime type detection in the question.

@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());
  }
}

这篇关于有没有任何Java标准类实现Iterable没有实现集合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆