3

我的(蒸馏)场景:

假设我有一个名为 的接口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,它内部保存了一个Foos的集合,但需要能够返回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的进行委托。这对我来说并不理想,因为该集合可能很大,而结果的接收者可能只需要前几个结果。

现在的问题:

谁能想到改变事情的方法,这样我就不需要拿那个具体集合的副本了?

理想情况下,我希望Results 构造函数是public Result(Collection<? extends E> delegate)(就像大多数Collections 一样),并让它以某种方式将该集合适应Collection<E>,但我无法弄清楚它可能是什么样子。

4

2 回答 2

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);
    }
}
于 2012-09-26T07:15:33.930 回答
1

如您所知,将 aCollection<? extends E>变为 a的危险Collection<E>在于,现在调用者可以将任何E内容放入其中。所以你必须排除这一点,你会没事的。Collections.unmodifiableCollection(Collection)这样做,它甚至会将结果呈现为Collection<E>.

编辑

Collection<? extends Interface> foos = new ArrayList<Foo>();
Collection<Interface> adapted = Collections.unmodifiableCollection(foos);
于 2012-09-26T07:11:21.857 回答