3

私の(蒸留された)シナリオ:

Interface、、およびと呼ばれるインターフェースがあるとしましょうclass Foo implements Interface

また、一般的な反復可能な「Result」クラスもあります。このクラスは、とりわけ、反復可能な処理を実行するためにコレクションに委任します。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そのコレクションはおそらく膨大であり、結果の受信者はおそらく最初のいくつかの結果のみを必要とするため、これは私にとって理想的ではありません。

今質問のために:

具体的なコレクションのコピーを取る必要がないように、誰かが物事を変える方法を考えることができますか?

理想的には、コンストラクターを(ほとんどResultのコンストラクターと同じように)して、そのコレクションをに何らかの形で適合させたいのですが、それがどのように見えるかを理解できませんでした。public Result(Collection<? extends E> delegate)CollectionCollection<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 に答える