Коллекция, представляющая объединение двух коллекций в Java - PullRequest
5 голосов
/ 15 ноября 2009

Существует ли класс, представляющий объединение коллекции с другой коллекцией? Этот класс должен представлять собой коллекцию сам по себе и должен делегировать все методы базовым (внутренним) коллекциям - не следует выделять дополнительную память или изменять исходные коллекции.

Пример использования:

Collection<String> foo = ...
Collection<String> bar = ...

// this should be O(1) memory and time
Collection<String> combined = concat(foo, bar);

if (combined.contains("Zee"))
  ...

for (String str : combined)
  System.out.println(str);

Ответы [ 7 ]

9 голосов
/ 16 ноября 2009

Как всегда для любых коллекций, посмотрите на google-collection . Если у вас есть Set с, а именно (не просто общая коллекция), вы хотите:

Set<String> combined = Sets.union(foo, bar);

, который создает неизменяемое представление двух наборов. То есть изменения в foo или bar будут отражены в combined (но combined.add() и т. Д. Не поддерживаются).

Для более общего случая у вас есть Iterables.concat(), но это просто позволяет вам перебирать объединенный элемент, интерфейс Iterable, очевидно, не включает contains, так что вы там немного запутались.

Другие классы утилит коллекций в google-collection (com.google.common.collect.Lists и com.google.common.collect.Collections2) не содержат никаких методов конкатенации. Не понимаю, почему они не могли, но в данный момент они этого не делают.

4 голосов
/ 15 ноября 2009

Ваш вопрос очень расплывчатый. Особенно "с другим предметом из другой коллекции" совершенно неясно.

Вы можете по крайней мере добавить содержимое другого Collection к текущему Collection, используя Collection#addAll(). Здесь Collection может быть любым из его подинтерфейсов / реализаций, например List или Set.

Пример:

List<String> foos = Arrays.asList("foo1", "foo2", "foo3");
List<String> bars = Arrays.asList("bar1", "bar2", "bar3");
foos.addAll(bars); // Now foos contains everything.

Редактировать : Или вы действительно хотите создать новый Collection на основе существующего Collection и затем добавить в него новый элемент? В этом случае просто создайте новый Collection с существующим Collection в качестве аргумента конструктора. E.g.:

List<String> foos = Arrays.asList("foo1", "foo2", "foo3");
List<String> bars = new ArrayList<String>(foos);
bars.add("bar"); // Now bars contains everything.
3 голосов
/ 20 ноября 2009

Нет, но написать это самому следует прямо

package ch.akuhn.util;

import java.util.Iterator;
import java.util.NoSuchElementException;

public class Concat {

    public static <T> Iterable<T> all(final Iterable<T>... iterables) {
        return new Iterable<T>() {
            @Override
            public Iterator<T> iterator() {
                return new Iterator<T>() {
                    Iterator<Iterable<T>> more = Arrays.asList(iterables).iterator();
                    Iterator<T> current = more.hasNext() ? more.next().iterator() : null;
                    @Override
                    public boolean hasNext() {
                        if (current == null) return false;
                        if (current.hasNext()) return true;
                        current = more.hasNext() ? more.next().iterator() : null;
                        return this.hasNext();
                    }

                    @Override
                    public T next() {
                        if (!hasNext()) throw new NoSuchElementException();
                        return current.next();
                    }

                    @Override
                    public void remove() {
                        throw new UnsupportedOperationException();
                    }
                };
            }
        };
    }

}

А потом

for (Object each: Concat.all(collection,whatever,etcetera,...)) {
    // ...
}

Только что написал этот код здесь, компилируйте на свой страх и риск!

PS, если ты собираешься написать модульные тесты для этого класса, пришли их мне.

2 голосов
/ 21 октября 2010

Коллекции Apache Commons также имеет более общий класс CompositeCollection , который можно использовать как интерфейс для произвольного числа Collection с.

2 голосов
/ 15 ноября 2009

Я думаю, что вы запрашиваете конструкцию Java, которая позволяет собирать коллекции без изменения исходных коллекций. Другими словами, у вас есть коллекции A и B, оба размера N и M соответственно. После вызова concat у вас все еще есть коллекции A и B, и их размеры по-прежнему равны N и M, однако у вас также есть коллекция C, которая указывает на A и B, делая ее размер N + M.

Ответ - нет, у Java нет ничего стандартного, что делает это ... Однако вы можете написать быструю оболочку, которая обернет серию коллекций и добавит эти коллекции в нее. (Все, что нужно сделать, это поддерживать ссылки на каждую из коллекций), и вы можете предоставлять методы get / insert по мере необходимости.

0 голосов
/ 10 февраля 2010

Попробуйте InterleavingEnumeration или коллекции Apache Commons ' ListUtils (ListUtils.union ())

0 голосов
/ 15 ноября 2009

Я не уверен, о чем ты спрашиваешь. Моя интерпретация вашего вопроса такова, что вы ищете метод add в Коллекции. Я не думаю, что это то, что вы спрашиваете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...