В моем приложении я использую стороннюю библиотеку (точнее Spring Data для MongoDB).
Методы этой библиотеки возвращаются Iterable<T>
, а остальная часть моего кода ожидает Collection<T>
.
Есть ли где-нибудь полезный метод, который позволит мне быстро конвертировать один в другой? Я бы хотел избежать создания цикла foreach
в моем коде для такой простой вещи.
java
collections
Ула Крукар
источник
источник
Ответы:
С Guava вы можете использовать Lists.newArrayList (Iterable) или Sets.newHashSet (Iterable) , среди других подобных методов. Это, конечно, скопирует все элементы в память. Если это не приемлемо, я думаю, что ваш код, который работает с ними, должен взять,
Iterable
а неCollection
. Гуава также предоставляет удобные методы для действий, которые вы можете делать наCollection
помощьюIterable
(например,Iterables.isEmpty(Iterable)
илиIterables.contains(Iterable, Object)
), но последствия для производительности более очевидны.источник
Lists.newArrayList(Iterable).clear()
это линейная или постоянная операция по времени?Collection
либо не могут быть реализованы для представления,Iterable
либо не будут эффективными, для меня не имеет особого смысла делать это.Iterables.concat()
но это даетIterable
, а неCollection
:(Iterables.concat()
. Более длинный ответ даетCollection
... Интересно, почему это не поддерживается чаще?В JDK 8+ без использования дополнительных библиотек:
Изменить: выше, для
Iterator
. Если вы имеете дело сIterable
,источник
iterable.forEach(target::add);
Вы можете написать свой собственный служебный метод для этого:
источник
Iterable
кCollection
- единственная проблема, я предпочел бы этот подход по сравнению с импортом большой сторонней библиотеки коллекций.Краткое решение с Java 8 с использованием
java.util.stream
:источник
IteratorUtils
сcommons-collections
IteratorUtils.toList()
использует итератор до Java 5, чтобы добавить элементы один за другим во вновь созданный список. Простой и, возможно, самый быстрый, но добавляет 734 кБ к вашему бинарному файлу, и вы можете сделать это самостоятельно, если сочтете этот метод лучшим.IteratorUtils
fromcommons-collections
может помочь (хотя они не поддерживают дженерики в последней стабильной версии 3.2.1):Версия 4.0 (которая сейчас находится в SNAPSHOT) поддерживает дженерики, и вы можете избавиться от них
@SuppressWarnings
.Обновление: проверка
IterableAsList
от Cactoos .источник
IterableUtils.toList(Iterable)
, этот метод удобен и используетсяIteratorUtils
под капотом, но также является нулевым (в отличие от негоIteratorUtils.toList
).Из CollectionUtils :
Вот полные источники этого полезного метода:
источник
Lists.newArrayList(someIterable).clear()
это линейная или постоянная операция по времени?addAll
, как видно из названия, он копирует значения итератора одно за другим; он создает копию, а не представление.CollectionUtils
пропустить создание коллекции в дополнительной строке.При этом не забывайте, что все коллекции конечны, а у Iterable нет никаких обещаний. Если что-то итерируемо, вы можете получить итератор и все.
будет расширен до:
it.hasNext () не требуется, чтобы когда-либо возвращать false. Таким образом, в общем случае вы не можете рассчитывать на то, что сможете конвертировать каждый Iterable в коллекцию. Например, вы можете перебирать все положительные натуральные числа, перебирать что-то с циклами, которые производят одни и те же результаты снова и снова и т. Д.
В противном случае: ответ Атри вполне в порядке.
источник
Я
FluentIterable.from(myIterable).toList()
много использую.источник
Это не ответ на ваш вопрос, но я считаю, что это решение вашей проблемы. Интерфейс
org.springframework.data.repository.CrudRepository
действительно имеет методы, которые возвращают,java.lang.Iterable
но вы не должны использовать этот интерфейс. Вместо этого используйте субинтерфейсы, в вашем случаеorg.springframework.data.mongodb.repository.MongoRepository
. Этот интерфейс имеет методы, которые возвращают объекты типаjava.util.List
.источник
Я использую свою пользовательскую утилиту для приведения существующей Коллекции, если она доступна.
Главный:
В идеале вышеупомянутое будет использовать ImmutableList, но ImmutableCollection не допускает нулевые значения, которые могут привести к нежелательным результатам.
тесты:
Я реализую аналогичные утилиты для всех подтипов коллекций (Set, List и т. Д.). Я думаю, что они уже будут частью Гуавы, но я не нашел это.
источник
Как только вы звоните
contains
,containsAll
,equals
,hashCode
,remove
,retainAll
,size
илиtoArray
, вы должны пройти через элементы в любом случае.Если вы иногда вызываете только такие методы, как
isEmpty
или,clear
я полагаю, вам будет лучше, если вы создадите коллекцию лениво. Например, вы можете иметь поддержкуArrayList
для хранения ранее повторенных элементов.Я не знаю ни одного такого класса в какой-либо библиотеке, но это должно быть довольно простое упражнение, чтобы написать.
источник
В Java 8 вы можете сделать это, чтобы добавить все элементы из
Iterable
кCollection
и вернуть его:Вдохновленный ответом @Afreys.
источник
Так как RxJava - это молот, а это похоже на гвоздь, вы можете сделать
источник
Вот SSCCE за отличный способ сделать это в Java 8
источник
Я столкнулся с подобной ситуацией при попытке получить a
List
изProject
s, а не по умолчанию,Iterable<T> findAll()
объявленный вCrudRepository
интерфейсе. Итак, в моемProjectRepository
интерфейсе (который выходит изCrudRepository
) я просто объявилfindAll()
метод, который возвращаетList<Project>
вместоIterable<Project>
.Я думаю, что это самое простое решение, не требующее логики преобразования или использования внешних библиотек.
источник
Два замечания
источник
Попробуйте
StickyList
от Cactoos :источник
Я не видел простого однострочного решения без каких-либо зависимостей. Я просто использую
источник
Вы можете использовать фабрики Eclipse Collections :
Вы также можете преобразовать в
Iterable
aLazyIterable
и использовать методы конвертера или любой другой доступный API.Все вышеперечисленные
Mutable
типы распространяютсяjava.util.Collection
.Примечание: я являюсь коммиттером для Eclipse Collections.
источник