2013-09-09 3 views
1

Вы знаете java.util.List-подобную реализацию, которая никогда не выделяет объекты для метода .add (T)? Я знаю HugeCollections, который хранит объекты в прямой памяти, но по-прежнему выделяет объекты в куче для изменения размера.Список impl, который не выделяет

Я понимаю, что это странная просьба. Это одноразовый прецедент, создающий инструмент для кучи.

Спасибо.

+1

Что именно вам нужно? Коллекция, которая разгружает все в неуправляемую память? Например, ArrayList не будет создавать объекты в 'add (T)', если он не изменит размер. Вы также можете написать реализацию List, в которой используется один массив фиксированного размера, который будет иметь детерминированные требования к памяти (он является статическим), а выделение одного массива увеличивает вероятность получения для него кучи кучи. – Pyranja

+1

Для меня это похоже на то, что вы пытаетесь профилировать код кода и делать книгу в одной JVM. Если да, вам, вероятно, лучше использовать http://docs.oracle.com/javase/6/docs/technotes/tools/share/jvisualvm.html или JProfiler. – BetaRide

+1

Вы можете использовать 'Arrays.asList', чтобы получить простую оболочку списка вокруг массива предварительно заданного размера. Вы не сможете добавить к нему, потому что его размер всегда будет размером массива поддержки, но вы можете установить элементы. –

ответ

2

Отъезд Banana, библиотека открытых примитивных коллекций с открытым исходным кодом. API-интерфейс списка не идентичен java.util.List, но он предлагает связанный список, который не выделяет память при добавлении элемента в список. Проверьте дополнительную информацию о проекте.

+0

LinkedList Banana # appendTail вызывает 'new int []', который вызывается через 'net.yadan.banana.memory.block.BlockAllocator # Increaseize. Вы экспериментировали с реализацией «IBlockAllocator» с прямой памятью? Похоже на естественное расширение lib, и тогда это послужило бы моим потребностям. Благодарю. –

+0

Increaseize обычно не вызывается, только когда в базовом хранилище заканчивается память. и даже когда он называется, он не вызывается для каждого объекта, который вы добавляете, поэтому накладные расходы создаются небольшими. Кроме того, вы можете настроить свой первоначальный размер хранилища, чтобы размер не требовался. Прямая память (небезопасная) - это то, с чем я планирую играть, но еще не сделал. –

1

Как было предложено, фиксированный размер ArrayList или Arrays::asList - это простой и эффективный вариант, если вы можете переносить список фиксированного размера.

Если вам нужен произвольно растущий список, тогда все сложнее. Если у вас есть контроль над объектами, которые вы храните, вы можете использовать intrusive container. Я не знаю никаких консервированных реализаций интрузивных контейнеров для Java, но вы можете посмотреть на Joachim Sauer's answer outlining how to write one. По сути, это полностью нормальный связанный список, но хранящиеся объекты предоставляют поля ссылок, поэтому вам не нужно выделять дополнительное хранилище для их добавления в список. Есть и другие преимущества, например, возможность удалить объект в O (1) раз, если у вас уже есть фактический объект. Конечно, есть и некоторые недостатки.

+0

Поскольку создание интрузивной обертки элементов потребует выделения, оно не работает для меня. Если только эта оболочка не была выделена из кучи, в этом случае это работает. Возможно, есть такая реализация, плавающая вокруг, прямой навязчивый список. –

+0

Нет, дело в том, что в интрузивом контейнере вещи, которые вы добавляете, удерживают указатели на ссылки. При добавлении в интрузивный контейнер существует нулевое распределение. Однако вы можете сделать это только в том случае, если вы контролируете классы объектов, которые вы добавляете, чтобы добавить поля указателя. Если вы этого не сделаете, вы не сможете использовать интрузивный сбор. Вы можете поместить непробиваемую оболочку вокруг элементов, которые хотите добавить, но тогда у вас только что появился обычный неинтрузивный список! –

+0

Gotcha. Тогда я не могу использовать интрузивный контейнер. –

0

Это довольно просто переопределить метод добавления, чтобы остановить его выращивания:

public class FixedArrayList<T> extends ArrayList<T> { 
    private final int size; 
    public FixedArrayList(int size) { 
     super(size); 
     this.size = size; 
    } 
    public void add(T t) { 
     if (size() == size) { 
      // throw exception or do nothing 
     } 
     super.add(t); 
    } 
} 

Вы можете переопределить addAll() тоже, если вы хотите.

+0

, если вы проверите реализацию ArrayList, вы увидите, что он выделяет объект для каждого элемента, который вы помещаете в список. –