3 回答

TA貢獻1876條經驗 獲得超7個贊
使用Guava,您可以使用Iterables.concat(Iterable<T> ...),它創建所有可迭代對象的實時視圖,并串聯在一起(如果更改可迭代對象,則串聯版本也會更改)。然后將串聯的可迭代對象包裝為Iterables.unmodifiableIterable(Iterable<T>)(我之前沒有看到只讀要求)。
從Iterables.concat( .. )JavaDocs:
將多個可迭代項合并為一個可迭代項。返回的Iterable具有迭代器,該迭代器遍歷輸入中每個Iterable的元素。直到必要時才輪詢輸入迭代器。remove() 當相應的輸入迭代器支持它時,返回的iterable的迭代器也將支持它。
雖然這并未明確表示這是實時視圖,但最后一句話暗示它是(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() {
}
}

TA貢獻1887條經驗 獲得超5個贊
使用Java的純Java 8解決方案Stream。
常數
假設private Collection<T> c, c2, c3。
一種解決方案:
public Stream<T> stream() {
return Stream.concat(Stream.concat(c.stream(), c2.stream()), c3.stream());
}
另一個解決方案:
public Stream<T> stream() {
return Stream.of(c, c2, c3).flatMap(Collection::stream);
}
可變數
假設private Collection<Collection<T>> cs:
public Stream<T> stream() {
return cs.stream().flatMap(Collection::stream);
}

TA貢獻1111條經驗 獲得超0個贊
如果您至少使用Java 8,請參閱我的其他答案。
如果您已經在使用Google Guava,請參見Sean Patrick Floyd的答案。
如果您堅持使用Java 7,并且不想包含Google Guava,則可以Iterables.concat()使用Iterable和最多編寫自己的(只讀)代碼Iterator:
常數
public static <E> Iterable<E> concat(final Iterable<? extends E> iterable1,
final Iterable<? extends E> iterable2) {
return new Iterable<E>() {
@Override
public Iterator<E> iterator() {
return new Iterator<E>() {
final Iterator<? extends E> iterator1 = iterable1.iterator();
final Iterator<? extends E> iterator2 = iterable2.iterator();
@Override
public boolean hasNext() {
return iterator1.hasNext() || iterator2.hasNext();
}
@Override
public E next() {
return iterator1.hasNext() ? iterator1.next() : iterator2.next();
}
};
}
};
}
可變數
@SafeVarargs
public static <E> Iterable<E> concat(final Iterable<? extends E>... iterables) {
return concat(Arrays.asList(iterables));
}
public static <E> Iterable<E> concat(final Iterable<Iterable<? extends E>> iterables) {
return new Iterable<E>() {
final Iterator<Iterable<? extends E>> iterablesIterator = iterables.iterator();
@Override
public Iterator<E> iterator() {
return !iterablesIterator.hasNext() ? Collections.emptyIterator()
: new Iterator<E>() {
Iterator<? extends E> iterableIterator = nextIterator();
@Override
public boolean hasNext() {
return iterableIterator.hasNext();
}
@Override
public E next() {
final E next = iterableIterator.next();
findNext();
return next;
}
Iterator<? extends E> nextIterator() {
return iterablesIterator.next().iterator();
}
Iterator<E> findNext() {
while (!iterableIterator.hasNext()) {
if (!iterablesIterator.hasNext()) {
break;
}
iterableIterator = nextIterator();
}
return this;
}
}.findNext();
}
};
}
添加回答
舉報