Кажется, здесь происходит большое заблуждение, что вы можете положиться на фактическую реализацию исходного кода. Это неверно, вы должны полагаться на контракт метода. Поскольку контракт не существует, вы не можете предполагать, что он что-то сделает, в любой момент времени базовая реализация может измениться. Например, посмотрите на следующую функцию:
/**
* Returns an empty Collection of Books.
*
*
* /
public Collection returnEmptyBooks()
{
return new HashSet<Book>();
}
Это означает, что я могу вернуть все, что реализует интерфейс Collection. Подпись плюс документация. Вы не могли бы предположить, что оно синхронизировано или что-то еще в этом роде. Вы также можете сделать вывод, что вы никогда не получите нуль от этого метода, если только контракт не был нарушен.
В случае, если никто не читает комментарии. Любое преобразование из одной структуры данных в другую предполагает итерацию. Вы не можете перейти от List к Set без итерации по всем элементам. То же самое относится и к преобразованию в массив. Вы должны заполнить массив, перебирая исходную структуру данных, поэтому его необходимо синхронизировать.