It's hard to know what to suggest to you without knowing the cases you need to optimize for.
For example, this simple wrapper around a map is a sparse 2D matrix optimized for setting and getting specific indices (doesn't need to "grow" at all), but bad for iterating over all indices.
public class SparseMatrix<T> {
private final Map<Coordinates, T> map = new HashMap<Coordinates, T>();
private final T defaultValue;
public SparseMatrix(T defaultValue) {
this.defaultValue = defaultValue;
}
private static class Coordinates {
private final int[] coordinates;
Coordinates(int... coordinates) {
this.coordinates = coordinates;
}
@Override
public boolean equals(Object o) {
return Arrays.equals(coordinates, ((Coordinates)o).coordinates);
}
@Override
public int hashCode() {
return Arrays.hashCode(coordinates);
}
}
public T get(int x, int y) {
T value = map.get(new Coordinates(x, y));
if ( value == null ) {
return defaultValue;
}
}
public T set(int x, int y, T val) {
return map.put(new Coordinates(x, y), val);
}
}
Usage:
SparseMatrix<Integer> matrix = new SparseMatrix<Integer>(0);
matrix.set(3, 5, 7);
int seven = matrix.get(3, 5);
int zero = matrix.get(3, 6); //not set yet, uses default
It can also be very easily adapted to N-dimensions. Of course in production code you wouldn't roll your own, you'd use a library that does a better job.
Vectoris more or less deprecated in Java, as compared toArrayList.xfor both the array andVector? You can't use the same variable name twice in the same scope; this is just adding confusion to your question.Listinterface over any particular implementation) and it has fallen out of favour with developers too. Plus, the docs recommend not using it when thread safety is not relevant. So it's de facto deprecated. For synchronized lists there are better implementations that don't bear the baggage of Vector, and are actually threadsafe where Vector requires explicit synchronization.