My (distilled) Scenario:
Let’s say I have an interface called Interface, and a class Foo implements Interface.
I also have a generic iterable “Result” class which among other things delegates to a collection to do the iterable stuff. The Result class does other stuff not relevant to the question. So:
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.
}
The collection passed into Result can potentially be huge, while users of the Result object are likely to stop iterating after a few elements (but I have no control over how many).
Then, I have another class, let’s call it Query, which internally holds a collection of Foos, but needs to be able to return Result. It currently looks like this:
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 ...;
}
}
So getAllData takes a copy of the data (as an ArrayList<Interface>), and passes that to the new Result for delegation. This is not ideal for me, as that collection is probably huge, and the receiver of the result probably only needs the first few results.
Now for the question:
Can anyone think of way of changing things such that I do not need to take that copy of the concrete collection?
Ideally, I’d like to have Results constructor be public Result(Collection<? extends E> delegate) (like most Collections do), and have it somehow adapt that collection to Collection<E>, but I have not been able to figure out what that might look like.
As you know, the danger in turning a
Collection<? extends E>into aCollection<E>is that now the caller can put anyEinto it. So you’d have to rule that out and you’d be fine.Collections.unmodifiableCollection(Collection)does just that and it will even present the result as aCollection<E>.Edit: