Với Guava, bạn có thể sử dụng Iterables.concat(Iterable<T> ...)
, nó tạo ra một chế độ xem trực tiếp của tất cả các tệp lặp, được nối thành một (nếu bạn thay đổi các tệp lặp, phiên bản được nối cũng thay đổi). Sau đó, bọc có thể lặp được nối kết với Iterables.unmodifiableIterable(Iterable<T>)
(tôi đã không thấy yêu cầu chỉ đọc trước đó).
Từ Iterables.concat( .. )
JavaDocs:
Kết hợp nhiều tệp lặp lại thành một tệp có thể lặp lại. Có thể lặp lại được trả về có một trình vòng lặp đi qua các phần tử của từng có thể lặp trong các đầu vào. Các trình vòng lặp đầu vào không được thăm dò ý kiến cho đến khi cần thiết. Trình vòng lặp của có thể lặp lại được trả về hỗ trợ remove()
khi trình vòng lặp đầu vào tương ứng hỗ trợ nó.
Mặc dù điều này không nói rõ ràng rằng đây là một chế độ xem trực tiếp, nhưng câu cuối cùng ngụ ý rằng nó là như vậy (chỉ hỗ trợ Iterator.remove()
phương thức nếu trình lặp hỗ trợ không thể thực hiện được trừ khi sử dụng chế độ xem trực tiếp)
Mã mẫu:
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);
Đầu ra:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 9999999]
Biên tập:
Theo Yêu cầu từ Damian, đây là một phương pháp tương tự trả về Chế độ xem Bộ sưu tập trực tiếp
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() {
}
}