将多个集合合并为单个逻辑集合? [英] Combine multiple Collections into a single logical Collection?

查看:247
本文介绍了将多个集合合并为单个逻辑集合?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设,我有一个恒定数量的集合(例如3 ArrayList)作为类的成员。现在,我想将所有元素暴露给其他类,以便它们可以简单地迭代所有元素(理想情况下,只读)。
我使用的是guava集合,我不知道如何使用guava iterables / iterator来生成内部集合的逻辑视图,而不用生成临时副本。

解决方案

使用Guava,您可以使用 Iterables.concat(Iterable< T& c $ c> ,它创建所有迭代器的实时视图,连接成一个(如果你改变迭代器,连接的版本也改变)。然后使用 Iterables.unmodifiableIterable(Iterable< T>) (我以前没有看到只读要求) / p>

Iterables.concat(..) JavaDocs:


将多个iterable组合成一个
单一可迭代。返回的可迭代
有一个遍历输入中每个可迭代的
元素的迭代器。
输入迭代器不轮询
直到必要。当相应的输入迭代器
支持它时,返回的
迭代器的迭代器支持 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>实现Collection< E> {

私人最终集锦<?扩展E> []项;

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();
}

}

/ **
*返回传递的集合的实时聚合集合视图。
*< p> ;
*除了{@link Collection#size()},{@link Collection#clear()},
* {@link Collection#isEmpty()}和{@link Iterable#iterator )}
* throw {@link UnsupportedOperationException}。
*< p>
*上述方法都不是线程安全的(也不会有一个简单的方法
*)。
* /
public static< T>集合< T> combine(
final Collection< ;? extends T> ... items){
return new JoinedCollectionView< T>(items);
}

private CollectionsX(){
}

}


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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆