ด้วย Guava คุณสามารถใช้Iterables.concat(Iterable<T> ...)
มันสร้างมุมมองสดของ iterables ทั้งหมดที่เชื่อมต่อกันเป็นหนึ่งเดียว (ถ้าคุณเปลี่ยน iterables เวอร์ชันที่ต่อกันจะเปลี่ยนไปด้วย) จากนั้นห่อส่วนที่สามารถทำซ้ำได้ด้วยIterables.unmodifiableIterable(Iterable<T>)
(ฉันไม่เห็นข้อกำหนดแบบอ่านอย่างเดียวก่อนหน้านี้)
จากIterables.concat( .. )
JavaDocs:
รวมการเล่นซ้ำหลายรายการเข้าด้วยกันในการทำซ้ำครั้งเดียว ตัวทำซ้ำที่ส่งคืนมีตัววนซ้ำที่ข้ามผ่านองค์ประกอบของแต่ละรายการที่ทำซ้ำได้ในอินพุต ตัววนซ้ำอินพุตจะไม่ได้รับการสำรวจจนกว่าจำเป็น ตัววนซ้ำที่ส่งคืนได้จะรองรับremove()
เมื่อตัววนซ้ำอินพุตที่เกี่ยวข้องรองรับ
แม้ว่าสิ่งนี้จะไม่ได้บอกอย่างชัดเจนว่านี่คือไลฟ์วิว แต่ประโยคสุดท้ายก็บอกเป็นนัยว่าเป็น (รองรับIterator.remove()
เมธอดเฉพาะในกรณีที่ตัววนซ้ำสำรองรองรับไม่ได้เว้นแต่จะใช้ไลฟ์วิว)
รหัสตัวอย่าง:
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);
เอาท์พุต:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 9999999]
แก้ไข:
ตามคำขอจาก Damian นี่คือวิธีการที่คล้ายกันซึ่งส่งคืนมุมมองคอลเลคชันสด
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() {
}
}