我的(蒸馏)场景:
假设我有一个名为Interface
和class Foo implements Interface
的界面。
我还有一个通用的可迭代“结果”类,除其他外,它委托给一个集合来做可迭代的东西。 Result类会执行与问题无关的其他内容。所以:
class Result<E> implements Iterable<E> {
private Collection<E> delegate;
public Result(Collection<E> delegate) {
this.delegate = delegate;
}
public Iterator<E> iterator() {
return delegate.iterator();
}
// ... other irrelevant stuff.
}
传递到Result
的集合可能很大,而Result
对象的用户可能会在几个元素之后停止迭代(但我无法控制多少元素)。
然后,我有另一个类,我们称之为Query,它在内部拥有Foo
的集合,但需要能够返回Result。它目前看起来像这样:
class Query {
private Collection<Foo> data;
public Result<Interface> getAllData() {
return new Result<Interface>(new ArrayList<Interface>(data));
}
// EDIT: Not all Result objects are of Interfaces.
public Result<SomeUnrelatedInterface> getSomeOtherData() {
return ...;
}
}
因此getAllData
会获取数据的副本(作为ArrayList<Interface>
),并将其传递给新的Result
进行委派。这对我来说并不理想,因为那个集合可能很庞大,结果的接收者可能只需要前几个结果。
现在提出问题:
任何人都可以想到改变事物的方式,这样我就不需要拍摄具体集合的副本吗?
理想情况下,我希望Result
的构造函数为public Result(Collection<? extends E> delegate)
(与大多数Collection
一样),并以某种方式使该集合适应Collection<E>
,但是我无法弄清楚那可能是什么样的。
答案 0 :(得分:3)
您可以使用以下变体吗?
class Result<E extends Interface>
implements Iterable<E> {
private Collection<E> delegate;
public Result(Collection<E> delegate) {
this.delegate = delegate;
}
public Iterator<E> iterator() {
return delegate.iterator();
}
}
class Query {
private Collection<Foo> data;
public Result<? extends Interface> getAllData() {
return new Result<Foo>(data);
}
}
答案 1 :(得分:1)
如您所知,将Collection<? extends E>
变为Collection<E>
的危险在于,现在调用者可以将任何E
放入其中。所以你必须排除这一点,你会没事的。 Collections.unmodifiableCollection(Collection)
就是这样做的,它甚至会将结果显示为Collection<E>
。
修改强>:
Collection<? extends Interface> foos = new ArrayList<Foo>();
Collection<Interface> adapted = Collections.unmodifiableCollection(foos);