将多个集合组合成一个逻辑集合? [英] Combine multiple Collections into a single logical Collection?
问题描述
假设,我有固定数量的集合(例如 3 个 ArrayLists)作为类的成员.现在,我想将所有元素公开给其他类,以便他们可以简单地迭代所有元素(理想情况下,只读).我正在使用番石榴集合,我想知道如何使用番石榴迭代器/迭代器来生成内部集合的逻辑视图制作临时副本.
有了 Guava,你可以使用 Iterables.concat(Iterable
,它创建所有可迭代对象的实时视图,连接为一个(如果您更改可迭代对象,则连接的版本也会更改).然后用 Iterables.unmodifiableIterable(Iterable
(我之前没有看到只读要求).
来自 Iterables.concat( .. )
JavaDocs:
将多个可迭代对象组合成一个单个可迭代.返回的可迭代对象有一个迭代器遍历输入中每个可迭代的元素.不轮询输入迭代器直到必要.返回的iterable 的迭代器支持 remove()
当对应的输入迭代器支持.
虽然这并没有明确说明这是一个实时视图,但最后一句暗示它是(支持 Iterator.remove()
方法仅当支持迭代器支持时才可行,除非使用实时视图)>
示例代码:
final Listfirst = Lists.newArrayList(1, 2, 3);最终列表<整数>第二个 = Lists.newArrayList(4, 5, 6);最终列表<整数>第三 = Lists.newArrayList(7, 8, 9);final Iterable全部 =Iterables.unmodifiableIterable(Iterables.concat(第一、第二、第三));System.out.println(all);第三.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 {静态类 JoinedCollectionView实现 Collection{私人最终收藏[] 项;public JoinedCollectionView(final Collection extends E>[] items) {this.items = 物品;}@覆盖public boolean addAll(final Collection extends E> c) {抛出新的 UnsupportedOperationException();}@覆盖公共无效清除(){for (final Collection extends E> coll : items) {coll.clear();}}@覆盖公共布尔包含(最终对象 o){抛出新的 UnsupportedOperationException();}@覆盖public boolean containsAll(final Collection<?> c) {抛出新的 UnsupportedOperationException();}@覆盖公共布尔 isEmpty() {返回 !iterator().hasNext();}@覆盖公共迭代器<E>迭代器(){返回 Iterables.concat(items).iterator();}@覆盖公共布尔删除(最终对象 o){抛出新的 UnsupportedOperationException();}@覆盖public boolean removeAll(final Collection<?>c){抛出新的 UnsupportedOperationException();}@覆盖公共布尔保留所有(最终集合> c){抛出新的 UnsupportedOperationException();}@覆盖公共整数大小(){int ct = 0;for (final Collection extends E> coll : items) {ct += coll.size();}返回 ct;}@覆盖公共对象[] toArray() {抛出新的 UnsupportedOperationException();}@覆盖公共 <T>T[] toArray(T[] a) {抛出新的 UnsupportedOperationException();}@覆盖公共布尔添加(E e){抛出新的 UnsupportedOperationException();}}/*** 返回传入集合的实时聚合集合视图.* <p>* 除 {@link Collection#size()}、{@link Collection#clear()} 之外的所有方法,* {@link Collection#isEmpty()} 和 {@link Iterable#iterator()}* 在返回的集合中抛出 {@link UnsupportedOperationException}.* <p>* 以上方法都不是线程安全的(也没有简单的方法*制作它们).*/公共静态<T>集合<T>结合(最终集合... 项目) {返回新的 JoinedCollectionView(items);}私人收藏X(){}}
Assume, I have a constant number of collections (e.g. 3 ArrayLists) as members of a class. Now, I want to expose all the elements to other classes so they can simply iterate over all elements (ideally, read only). I'm using guava collections and I wonder how I could use guava iterables/iterators to generate a logical view on the internal collections without making temporary copies.
With Guava, you can use Iterables.concat(Iterable<T> ...)
, it creates a live view of all the iterables, concatenated into one (if you change the iterables, the concatenated version also changes). Then wrap the concatenated iterable with Iterables.unmodifiableIterable(Iterable<T>)
(I hadn't seen the read-only requirement earlier).
From the Iterables.concat( .. )
JavaDocs:
Combines multiple iterables into a single iterable. The returned iterable has an iterator that traverses the elements of each iterable in inputs. The input iterators are not polled until necessary. The returned iterable's iterator supports
remove()
when the corresponding input iterator supports it.
While this doesn't explicitly say that this is a live view, the last sentence implies that it is (supporting the Iterator.remove()
method only if the backing iterator supports it is not possible unless using a live view)
Sample Code:
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);
Output:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 9999999]
Edit:
By Request from Damian, here's a similar method that returns a live Collection View
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() {
}
}
这篇关于将多个集合组合成一个逻辑集合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!