亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

將多個集合合并為一個邏輯集合?

將多個集合合并為一個邏輯集合?

大話西游666 2019-12-25 15:35:23
假設我有恒定數量的集合(例如3個ArrayList)作為類的成員。現在,我想將所有元素公開給其他類,以便它們可以簡單地遍歷所有元素(理想情況下為只讀)。我正在使用番石榴集合,不知道如何使用番石榴可迭代器/迭代器在內部集合上生成邏輯視圖而無需制作臨時副本。
查看完整描述

3 回答

?
幕布斯6054654

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() {

    }


}


查看完整回答
反對 回復 2019-12-25
?
慕工程0101907

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

}


查看完整回答
反對 回復 2019-12-25
?
catspeake

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

        }

    };

}


查看完整回答
反對 回復 2019-12-25
  • 3 回答
  • 0 關注
  • 695 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號