Java:如何将集合从 Apache commons collection4 lib 传递给 chainedIterator(Collection<Iterator<? extends E>> iterators)?
Java : How to pass collection to chainedIterator(Collection<Iterator<? extends E>> iterators) from Apache commons collection4 lib?
我在下面的代码中尝试使用 org.apache.commons.collections4.IteratorUtils
(Apache commons collection4 lib)中的 chainedIterator(Collection<Iterator<? extends E>> iterators)
,但出现编译时错误。
这是我的代码..
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>>)
}
问题是方法签名
public static <E> Iterator<E>
chainedIterator(Collection<Iterator<? extends E>> iterators)
限制太多。
它说要 return 一个 Iterator<Resource>
你必须传入一个 Collection<Iterator<? extends Resource>>
。
反映实际意图的方法签名必须是
public static <E> Iterator<E>
chainedIterator(Collection<? extends Iterator<? extends E>> iterators)
然后,您的代码将无错误地编译,并且可以证明使用该宽松签名实现该方法是可能的,例如
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();
}
另见 How to convert an iterator to a stream?
但是您可以通过提供它所需要的内容来解决当前方法签名的问题。只需更改声明
Collection<Iterator<Resource>> its = new ArrayList<Iterator<Resource>>();
至
Collection<Iterator<? extends Resource>> its = new ArrayList<>();
然后,您可以按原样使用 IteratorUtils
。但请注意,您根本不需要第三方库。整个方法只能使用内置功能来实现,比如
private Iterator<Resource> getResources() {
return Arrays.stream(getParameterValues())
.map(path -> getOnlyResource(path))
.flatMap(it -> StreamSupport.stream(
Spliterators.spliteratorUnknownSize(it, Spliterator.ORDERED), false))
.iterator();
}
这类似于上面的示例 chainedIterator
实现,但不需要首先将迭代器收集到集合中的步骤。相反,它是惰性的,所以如果调用者没有遍历所有元素,这个解决方案甚至可能会跳过不必要的 getOnlyResource
调用。
我在下面的代码中尝试使用 org.apache.commons.collections4.IteratorUtils
(Apache commons collection4 lib)中的 chainedIterator(Collection<Iterator<? extends E>> iterators)
,但出现编译时错误。
这是我的代码..
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>>)
}
问题是方法签名
public static <E> Iterator<E>
chainedIterator(Collection<Iterator<? extends E>> iterators)
限制太多。
它说要 return 一个 Iterator<Resource>
你必须传入一个 Collection<Iterator<? extends Resource>>
。
反映实际意图的方法签名必须是
public static <E> Iterator<E>
chainedIterator(Collection<? extends Iterator<? extends E>> iterators)
然后,您的代码将无错误地编译,并且可以证明使用该宽松签名实现该方法是可能的,例如
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();
}
另见 How to convert an iterator to a stream?
但是您可以通过提供它所需要的内容来解决当前方法签名的问题。只需更改声明
Collection<Iterator<Resource>> its = new ArrayList<Iterator<Resource>>();
至
Collection<Iterator<? extends Resource>> its = new ArrayList<>();
然后,您可以按原样使用 IteratorUtils
。但请注意,您根本不需要第三方库。整个方法只能使用内置功能来实现,比如
private Iterator<Resource> getResources() {
return Arrays.stream(getParameterValues())
.map(path -> getOnlyResource(path))
.flatMap(it -> StreamSupport.stream(
Spliterators.spliteratorUnknownSize(it, Spliterator.ORDERED), false))
.iterator();
}
这类似于上面的示例 chainedIterator
实现,但不需要首先将迭代器收集到集合中的步骤。相反,它是惰性的,所以如果调用者没有遍历所有元素,这个解决方案甚至可能会跳过不必要的 getOnlyResource
调用。