Mit Guava können Iterables.concat(Iterable<T> ...)
Sie eine Live-Ansicht aller iterierten Elemente erstellen, die zu einer verkettet sind (wenn Sie die iterablen Elemente ändern, ändert sich auch die verkettete Version). Wickeln Sie dann die verkettete iterable mit ein Iterables.unmodifiableIterable(Iterable<T>)
(ich hatte die schreibgeschützte Anforderung zuvor nicht gesehen).
Aus den Iterables.concat( .. )
JavaDocs:
Kombiniert mehrere Iterables zu einem einzigen Iterable. Die zurückgegebene Iterable verfügt über einen Iterator, der die Elemente jeder Iterable in Eingaben durchläuft. Die Eingabe-Iteratoren werden erst bei Bedarf abgefragt. Der Iterator des zurückgegebenen Iterables unterstützt, remove()
wenn der entsprechende Eingabe-Iterator dies unterstützt.
Dies bedeutet zwar nicht ausdrücklich, dass es sich um eine Live-Ansicht handelt, der letzte Satz impliziert jedoch, dass dies der Fall ist (die Unterstützung der Iterator.remove()
Methode nur, wenn der Backing-Iterator dies unterstützt, ist nur mit einer Live-Ansicht möglich).
Beispielcode:
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);
Ausgabe:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 9999999]
Bearbeiten:
Auf Anfrage von Damian gibt es eine ähnliche Methode, die eine Live-Sammlungsansicht zurückgibt
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() {
}
}