简体   繁体   English

Java:如何将集合传递给chainedIterator(集合<iterator<? extends e> &gt; 迭代器)来自 Apache commons collection4 lib? </iterator<?>

[英]Java : How to pass collection to chainedIterator(Collection<Iterator<? extends E>> iterators) from Apache commons collection4 lib?

I have below code where trying to use chainedIterator(Collection<Iterator<? extends E>> iterators) from org.apache.commons.collections4.IteratorUtils (Apache commons collection4 lib) but giving compile time error.我在下面的代码中尝试使用来自org.apache.commons.collections4.IteratorUtils (Apache commons collection4 lib) 的chainedIterator(Collection<Iterator<? extends E>> iterators) ) 但给出编译时错误。

Here is my code..这是我的代码..

private Iterator<Resource> getResources() {
        String[] paths = getParameterValues();
        Collection<Iterator<Resource>> its = new ArrayList<Iterator<Resource>>();       
        for (int i = 0; i < paths.length; i++) {
            String path = paths[i];         
            its.add(getOnlyResource(path));
        }
        return IteratorUtils.chainedIterator(its); //gives compile error - The method chainedIterator(Iterator<? extends E>...) in the type IteratorUtils is not applicable for the arguments (Collection<Iterator<Resource>>)
    }

The problem is the method signature问题是方法签名

public static <E> Iterator<E>
    chainedIterator(Collection<Iterator<? extends E>> iterators)

which is too restrictive.这太严格了。

It says that to return an Iterator<Resource> you have to pass in a Collection<Iterator<? extends Resource>>它说要返回一个Iterator<Resource>你必须传入一个Collection<Iterator<? extends Resource>> Collection<Iterator<? extends Resource>> . Collection<Iterator<? extends Resource>>

The method signature reflecting the actual intention has to be反映实际意图的方法签名必须是

public static <E> Iterator<E>
    chainedIterator(Collection<? extends Iterator<? extends E>> iterators)

Then, your code would compile without error and it can be shown that implementing the method with that relaxed signature is possible, eg然后,您的代码将无错误地编译,并且可以证明使用该宽松签名实现该方法是可能的,例如

public static <E> Iterator<E>
    chainedIterator(Collection<? extends Iterator<? extends E>> iterators) {

    if(iterators.isEmpty()) return Collections.emptyIterator();
    return iterators.stream()
        .flatMap(it -> StreamSupport.stream(
            Spliterators.<E>spliteratorUnknownSize(it, Spliterator.ORDERED), false))
        .iterator();
}

See also How to convert an iterator to a stream?另请参阅如何将迭代器转换为 stream?


But you can work-around the problem of the current method signature by providing exactly what it demands.但是您可以通过准确提供当前方法签名的要求来解决当前方法签名的问题。 Just change the declaration只需更改声明

Collection<Iterator<Resource>> its = new ArrayList<Iterator<Resource>>();

to

Collection<Iterator<? extends Resource>> its = new ArrayList<>();

Then, you can use the IteratorUtils as-is.然后,您可以按原样使用IteratorUtils But mind that you don't need a 3rd party library at all.但请注意,您根本不需要 3rd 方库。 The entire method can be implemented using built-in features only like整个方法只能使用内置功能来实现,例如

private Iterator<Resource> getResources() {
    return Arrays.stream(getParameterValues())
        .map(path -> getOnlyResource(path))
        .flatMap(it -> StreamSupport.stream(
            Spliterators.spliteratorUnknownSize(it, Spliterator.ORDERED), false))
        .iterator();
}

This is similar to the example chainedIterator implementation above, but does not require the step of first collecting the iterators into a collection.这类似于上面的示例chainedIterator实现,但不需要首先将迭代器收集到集合中的步骤。 Instead, it's lazy, so if the caller doesn't iterate over all elements, this solution might even skip unnecessary getOnlyResource calls.相反,它是惰性的,所以如果调用者没有遍历所有元素,这个解决方案甚至可能会跳过不必要getOnlyResource调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM