Я думаю, что если вы следуете духу правил, то, конечно, вы не сможете добиться большего, чем O (log n) времени, чтобы получить или установить элемент. Причина этого заключается в том, что каждый объект, который вы создаете, может хранить не более фиксированного количества элементов данных и фиксированного количества ссылок на другие объекты , определяемых количеством полей в этом объекте.
Пусть D будет (максимальным) числом элементов данных, которое содержит объект, а F будет (максимальным) числом опорных полей, которые содержит объект. Для ясности, D подсчитывает поля, используемые для хранения фактических данных «массива», а F подсчитывает поля, которые используются для самой структуры данных.
Если время доступа равно O (1), тогда вы можете для доступа к ячейке следует не более O (1) ссылок, что означает, что размер вашего «массива» ограничен O (D * F ^ R), где R - это фиксированное ограничение на количество ссылок, которым вы можете следовать для выполнения. одна операция. Если все три из D, F и R являются постоянными, то размер вашего «массива» будет таким же. Из этого следует, что эмуляция характеристик производительности структуры данных массива произвольного размера невозможна с учетом ограничений.
Этот аргумент можно расширить еще немного, чтобы доказать, что R должно быть не менее O (log n) в порядок достижения n отдельных элементов данных; то есть, чтобы получить доступ к элементу, вы должны следовать как минимум за O (log n) ссылками. Вы можете использовать полное двоичное дерево для фактического достижения этой границы.
Тем не менее, есть по крайней мере один способ следовать букве правил, не следуя их духу.
Вам строго запрещено использовать массивы или библиотечные классы JCF, но единственные правила в отношении сторонних библиотечных классов заключаются в том, что вы не можете импортировать их или ссылаться на них по полному имени. Вы можете использовать метод ClassLoader.loadClass
, чтобы загрузить класс коллекции из сторонней библиотеки, создать его экземпляр с помощью отражения, присвоить его переменной типа Object
, а затем вызвать его методы с помощью отражения. Это технически разрешено, потому что loadClass
принимает "двоичное имя", а не "полностью определенное имя" класса, который вы хотите загрузить. (Я оставлю это на усмотрение адвокатов, чтобы выяснить, нужно ли вам загружать класс, двоичное имя которого также не полностью квалифицированное имя.)
Для педантов: я интерпретирую правило о массивах гласит, что у вас не должно быть массивов в вашем коде (кроме, предположительно, String[] args
в основном методе), а не в массивах в чужих кодах, которые ваш код звонки; в противном случае, например, вашей программе запрещено печатать любые выходные данные, потому что данные, записанные в System.out
, буферизуются в массиве. Я думаю, что вряд ли это правило предназначено для запрета на печать любого вывода.