Причина, по которой вы не можете его скомпилировать, заключается в том, что в итоге вы получаете следующее (не используете var
, поэтому типы легко видны).
List<Iterable<T>> x = List.of(iter); // List of Iterable<T> with a single element: "iter"
x.add(v); // Won't compile because "v" is an Object, not an Iterable<T>
x.add((Iterable<T>) v); // Compiles with warnings, will probably fail with ClassCastException at runtime
x.add((T) v); // Won't compile, "v" is being cast to "T" which is not an Iterable<T>
Несмотря на все это, List.of
фабричные методы возвращают неизменяемые List
.Даже если бы вы могли получить его для компиляции, вы получите UnsupportedOperationException
, генерируемый во время выполнения.
Интерфейс Iterable
не предоставляет никакого API для добавления элементов, только удаляя элементы черезIterator
(если реализация поддерживает это).Это означает, что вы не можете добавить элемент к Iterable
в общем смысле.Если вам нужен API, который предоставляет Iterable
, вы можете добавлять элементы к вам, не следует возвращать Iterable
для начала.Предпочитаю возвращать Collection
или, так как вам нужно добавить элементы, List
или Deque
.Обратите внимание, что все упомянутые альтернативы простираются от интерфейса Iterable
:
Если по какой-либо причине необходимо вернуть Iterable
, или проблема заключается всторонний API, тогда лучше всего создать копию и добавить в нее свои элементы.
Iterable<T> iter = ...;
Object v = ...;
List<Object> copy = new ArrayList<>();
copy.add(v); // add v first
iter.forEach(copy::add); // add rest of iterable after v
Обратите внимание, что List
- это список Object
сейчас.Вы указали, что у вас есть Iterable
из T
, к которому вы хотите добавить Object
.Без дополнительной информации общий предок между этими двумя типами - Object
.
Если вам не нужна копия, и вы знаете, что реализация Iterable
является чем-то вроде модифицируемой List
, вы можете разыграть, затем добавить:
((List<T>) iter).add(0, v); // in this case "v" must be of type "T"
Однако тот факт, что у вас есть Iterable
, указывает на то, что созданный API не хочет и не ожидает, что он будет изменен вами, потребителемуказанный API.