Dengan Guava, Anda dapat menggunakannya Iterables.concat(Iterable<T> ...)
, ini membuat tampilan langsung dari semua iterable, digabungkan menjadi satu (jika Anda mengubah iterable, versi gabungan juga berubah). Kemudian bungkus iterable bersambung dengan Iterables.unmodifiableIterable(Iterable<T>)
(saya belum melihat persyaratan hanya-baca sebelumnya).
Dari Iterables.concat( .. )
JavaDocs:
Menggabungkan beberapa iterable menjadi satu iterable. Iterable yang dikembalikan memiliki iterator yang melintasi elemen dari setiap iterable dalam input. Iterator masukan tidak disurvei sampai diperlukan. Iterator iterable yang dikembalikan mendukung remove()
ketika iterator input yang sesuai mendukungnya.
Meskipun ini tidak secara eksplisit mengatakan bahwa ini adalah tampilan langsung, kalimat terakhir menyiratkan bahwa itu (mendukung Iterator.remove()
metode hanya jika iterator pendukung mendukungnya tidak mungkin kecuali menggunakan tampilan langsung)
Kode sampel:
final List<Integer> first = Lists.newArrayList(1, 2, 3);
final List<Integer> second = Lists.newArrayList(4, 5, 6);
final List<Integer> third = Lists.newArrayList(7, 8, 9);
final Iterable<Integer> all =
Iterables.unmodifiableIterable(
Iterables.concat(first, second, third));
System.out.println(all);
third.add(9999999);
System.out.println(all);
Keluaran:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 9999999]
Edit:
Berdasarkan Permintaan dari Damian, berikut adalah metode serupa yang mengembalikan Tampilan Koleksi langsung
public final class CollectionsX {
static class JoinedCollectionView<E> implements Collection<E> {
private final Collection<? extends E>[] items;
public JoinedCollectionView(final Collection<? extends E>[] items) {
this.items = items;
}
@Override
public boolean addAll(final Collection<? extends E> c) {
throw new UnsupportedOperationException();
}
@Override
public void clear() {
for (final Collection<? extends E> coll : items) {
coll.clear();
}
}
@Override
public boolean contains(final Object o) {
throw new UnsupportedOperationException();
}
@Override
public boolean containsAll(final Collection<?> c) {
throw new UnsupportedOperationException();
}
@Override
public boolean isEmpty() {
return !iterator().hasNext();
}
@Override
public Iterator<E> iterator() {
return Iterables.concat(items).iterator();
}
@Override
public boolean remove(final Object o) {
throw new UnsupportedOperationException();
}
@Override
public boolean removeAll(final Collection<?> c) {
throw new UnsupportedOperationException();
}
@Override
public boolean retainAll(final Collection<?> c) {
throw new UnsupportedOperationException();
}
@Override
public int size() {
int ct = 0;
for (final Collection<? extends E> coll : items) {
ct += coll.size();
}
return ct;
}
@Override
public Object[] toArray() {
throw new UnsupportedOperationException();
}
@Override
public <T> T[] toArray(T[] a) {
throw new UnsupportedOperationException();
}
@Override
public boolean add(E e) {
throw new UnsupportedOperationException();
}
}
/**
* Returns a live aggregated collection view of the collections passed in.
* <p>
* All methods except {@link Collection#size()}, {@link Collection#clear()},
* {@link Collection#isEmpty()} and {@link Iterable#iterator()}
* throw {@link UnsupportedOperationException} in the returned Collection.
* <p>
* None of the above methods is thread safe (nor would there be an easy way
* of making them).
*/
public static <T> Collection<T> combine(
final Collection<? extends T>... items) {
return new JoinedCollectionView<T>(items);
}
private CollectionsX() {
}
}