В общем, нет хорошего способа заставить ваши объекты в очереди занимать непрерывный кусок памяти. Однако есть некоторые методы, которые подходят для особых случаев.
На высоком уровне методы включают использование байтовых массивов и «сериализацию» данных в массив и из него. Это на самом деле довольно эффективно, если вы храните очень простые объекты. Например, если вы храните набор 2D точек + весов, вы можете просто написать байтовый эквивалент веса, координаты x, координаты y.
Проблема на данный момент, конечно, заключается в распределении экземпляров при просмотре / прослушивании. Вы можете избежать этого, используя обратный вызов.
Обратите внимание, что даже в тех случаях, когда сам сохраняемый объект является сложным, использование метода, подобного этому, где вы сохраняете один массив для весов и отдельный массив ссылок для реальных объектов, позволяет вам избегать следования ссылкам на объекты до абсолютно необходимо.
Возвращаясь к подходу для хранения простого неизменяемого типа значения, вот неполный набросок того, что вы могли бы сделать:
abstract class LowLevelPQ<T> {
interface DataHandler<R, T> {
R handle(byte[] source, int startLoc);
}
LowLevelPQ(int entryByteSize) { ... }
abstract encode(T element, byte[] target, int startLoc);
abstract T decode(byte[] source, int startLoc);
abstract int compare(byte[] data, int startLoc1, int startLoc2);
abstract <R> R peek(DataHandler<R, T> handler) { ... }
abstract <R> R pop(DataHandler<R, T> handler) { ... }
}
class WeightedPoint {
WeightedPoint(int weight, double x, double y) { ... }
double weight() { ... }
double x() { ... }
...
}
class WeightedPointPQ extends LowLevelPQ<WeightedPoint> {
WeightedPointPQ() {
super(4 + 8 + 8); // int,double,double
}
int compare(byte[] data, int startLoc1, int startLoc2) {
// relies on Java's big endian-ness
for (int i = 0; i < 4; ++i) {
int v1 = 0xFF & (int) data[startLoc1];
int v2 = 0xFF & (int) data[startLoc2];
if (v1 < v2) { return -1; }
if (v1 > v2) { return 1; }
}
return 0;
}
...
}