Предположим, у меня есть постоянное количество коллекций (например, 3 ArrayLists) в качестве членов класса. Теперь я хочу предоставить все элементы другим классам, чтобы они могли просто перебирать все элементы (в идеале, только для чтения). Я использую коллекции guava, и мне интересно, как я могу использовать итераторы / итераторы guava для создания логического представления внутренних коллекций без создания временных копий.
java
collections
guava
Newgre
источник
источник
Ответы:
С Guava вы можете использовать
Iterables.concat(Iterable<T> ...)
, он создает живое представление всех итераций, объединенных в один (если вы измените итерации, объединенная версия также изменится). Затем оберните объединенную итерацию с помощьюIterables.unmodifiableIterable(Iterable<T>)
(ранее я не видел требования только для чтения).Из
Iterables.concat( .. )
JavaDocs:Хотя это явно не говорит о том, что это живое представление, последнее предложение подразумевает, что это так (поддержка
Iterator.remove()
метода, только если поддерживающий итератор поддерживает, это невозможно, если не используется живое представление)Образец кода:
Вывод:
Редактировать:
По запросу Дамиана вот аналогичный метод, который возвращает представление коллекции в реальном времени.
источник
Iterables.unmodifiableIterable(iterable)
Iterables.concat
производитIterable
, а неCollection
. Мне нуженCollection
вид.size()
это то, что мне нужно.add()
выбрасывать исключение - это хорошо - меня не волнует этот метод. API коллекций не работает, и никто ничего не может с этим поделать.Collection.add()
,Iterator.remove()
Бла.Простые решения Java 8 с использованием
Stream
.Постоянное число
Предполагая
private Collection<T> c, c2, c3
.Одно решение:
Другое решение:
Номер переменной
Предполагая
private Collection<Collection<T>> cs
:источник
Если вы используете хотя бы Java 8, см. Мой другой ответ .
Если вы уже используете Google Guava, см . Ответ Шона Патрика Флойда .
Если вы застряли на Java 7 и не хотите включать Google Guava, вы можете написать свой собственный (только для чтения),
Iterables.concat()
используя не болееIterable
иIterator
:Постоянное число
Номер переменной
источник
Вы можете создать новый
List
иaddAll()
свои другиеList
. Затем верните неизменяемый список с помощьюCollections.unmodifiableList()
.источник
ArrayList
просто выделяет пространство и вызовыSystem.arraycopy()
под капотом. Не может быть ничего более эффективного, чем это.Вот мое решение для этого:
EDIT - немного изменил код
источник
hasNext()
иnext()
. Первый изменяет состояние вашего итератора, а второй - нет. Должно быть наоборот. Звонокnext()
без звонкаhasNext()
всегда уступитnull
. ВызовhasNext()
без вызоваnext()
отбрасывает элементы. Вашnext()
тоже не бросаетNoSuchElementException
, а вместо этого возвращаетсяnull
.