Поскольку вы используете Set<Pixel>
, вы должны создать новый экземпляр Pixel
, чтобы проверить, существует ли он в наборе или нет.
Если набор содержит N
элементов после вызова B.function
метод, вы будете создавать дополнительные N
Pixel
узлов. Если все элементы новые, вы просто добавляете их для установки, в противном случае Garbage Collection
необходимо их развернуть. Один из недостатков заключается в том, что нам нужно создать m
(тогда m <= N
- количество Pixel
-ов, которые уже существуют в наборе), а затем нам нужно собрать их по GC
. Насколько велико соотношение m/N
, зависит от вашего алгоритма и того, что вы на самом деле делаете.
Позволяет рассчитать, сколько памяти нам нужно использовать для набора N = 1_000_000
пикселей. Мы знаем, что int
- это 4 bytes
, а double
- это 8 bytes
, давайте добавим дополнительные 8 bytes
для объекта и 8 bytes
для ссылки. Это дает 32 bytes
для каждого экземпляра Pixel
объекта. Нам нужно создать N
объектов, что дает 32MB
. Давайте предположим, что наше соотношение составляет 50%
, поэтому 16MB
мы выделили просто для того, чтобы проверить, что оно не нужно.
Если это стоимость, которую вы не можете заплатить, вам необходимо разработать алгоритм, который позволит вам перебирать Set<Pixel>
при заказе от left-to-right
. Таким образом, левый сосед Pixel
X
находится перед X
.
Предположим, что левый сосед Pixel
X(x, y)
равен пикселю X'(x - 1, y)
. Pixel
B(0, y)
не имеет соседа. Вам необходимо использовать TreeSet
и реализовать интерфейс Comparable<Pixel>
в классе Pixel
. Простая реализация может выглядеть следующим образом:
@Override
public int compareTo(Pixel o) {
return this.y == o.y ? this.x - o.x : this.y - o.y;
}
Это позволяет вам перебирать набор в порядке слева направо: (0, 0), (1, 0), ...., (x - 1, y), (x, y), (x + 1, y), ... , (maxX, maxY)
. Поэтому, когда вы выполняете итерацию, вы можете проверить, является ли предыдущий элемент левым соседом текущего Pixel
. Пример реализации может выглядеть следующим образом:
void addNeighboursIfNeeded() {
Set<Pixel> neighbours = new HashSet<>(pixels.size());
Pixel last = null;
for (Pixel p : pixels) {
if (p.getX() == 0 || p.isLeftNeighbour(last)) {
// a left border pixel
// or last checked element is a left neighbour of current pixel.
last = p;
continue;
}
// last element was not our left-neighbour so we need to call b method
Pixel left = b.getLeft(p);
neighbours.add(left);
last = p;
}
// add all new neigbours
pixels.addAll(neighbours);
}
Это должно позволить вам сохранить эту память, которая выделена для дублированных Pixel
объектов.