Вы можете копировать вставить разреженный вектор из моего проекта Hapax: ch.akuhn.matrix.SparseVector
PS: на все другие ответы и комментарии, которые Dont почему использование обращали внимание на карту слишком медленно. Он медленный, потому что карта помещает все индексы в объекты Integer!
Редкий вектор, представленный здесь, является быстрым для чтения и добавления значений, но не для случайных индексов. Это оптимально для сценария, в котором вы сначала создаете вектор смены, но добавляете значения в порядке возрастания индексов, а затем используете карту для чтения в основном.
Важные методы в разреженном векторе классе
// ...
public class SparseVector {
/*default*/ int[] keys;
/*default*/ int size, used;
/*default*/ double[] values;
public SparseVector(int size, int capacity) {
assert size >= 0;
assert capacity >= 0;
this.size = size;
this.keys = new int[capacity];
this.values = new double[capacity];
}
public double get(int key) {
if (key < 0 || key >= size) throw new IndexOutOfBoundsException(Integer.toString(key));
int spot = Arrays.binarySearch(keys, 0, used, key);
return spot < 0 ? 0 : values[spot];
}
public boolean isUsed(int key) {
return 0 <= Arrays.binarySearch(keys, 0, used, key);
}
public double put(int key, double value) {
if (key < 0 || key >= size) throw new IndexOutOfBoundsException(Integer.toString(key));
int spot = Arrays.binarySearch(keys, 0, used, key);
if (spot >= 0) return values[spot] = (float) value;
else return update(-1 - spot, key, value);
}
public void resizeTo(int newSize) {
if (newSize < this.size) throw new UnsupportedOperationException();
this.size = newSize;
}
public int size() {
return size;
}
private double update(int spot, int key, double value) {
// grow if reaching end of capacity
if (used == keys.length) {
int capacity = (keys.length * 3)/2 + 1;
keys = Arrays.copyOf(keys, capacity);
values = Arrays.copyOf(values, capacity);
}
// shift values if not appending
if (spot < used) {
System.arraycopy(keys, spot, keys, spot + 1, used - spot);
System.arraycopy(values, spot, values, spot + 1, used - spot);
}
used++;
keys[spot] = key;
return values[spot] = (float) value;
}
public int used() {
return used;
}
public void trim() {
keys = Arrays.copyOf(keys, used);
values = Arrays.copyOf(values, used);
}
}
Доступ к HashMap слишком медленный? Я знаю, что есть накладные расходы с использованием HashMap, но это только вызов ваших методов hashCode и equals. Вы убедились, что эти методы имеют оптимальную реализацию? – Malaxeur
Какой доступ вам нужен, чтобы быть быстрым? Трудно поверить, что HashMap вызывает много накладных расходов над гипотетическим оптимальным решением, если ваши индексы не имеют хеша должным образом ... –
@pascal HashMap помещает все индексы в объекты Integer, это ** ** медленно. – akuhn