0

Basically, I want to create a 2-D array that grows in size at runtime. Could I do this using a vector in Java?

Would these be right then?

int [] [] x = new x [100] [100];

Vector x= new Vector();

To add elements into the array-

for i=0 to 99
   for j=0 to 99
   x.addElement(x[i] [j]);

essentially, it would be just the same like referencing any other object, only here, I've to specify the index numbers as well, right?

I'm a novice at Java. So I'd appreciate any help!

Floose
  • 525
  • 2
  • 7
  • 15
  • 3
    `Vector` is more or less deprecated in Java, as compared to `ArrayList`. – Louis Wasserman Nov 14 '12 at 04:59
  • 1
    Why are you reusing the name `x` for both the array and `Vector`? You can't use the same variable name twice in the same scope; this is just adding confusion to your question. – Mark Peters Nov 14 '12 at 05:04
  • You cannot create a 2D structure that automatically grows in both dimensions using just the collections in JDK. – Affe Nov 14 '12 at 05:05
  • @Affe ArrayList of ArrayList does it count ? – dreamcrash Nov 14 '12 at 05:10
  • @dreamcrash It would be difficult to make sure that all of the secondary arraylists contained within the main arraylist were the same length, although it would be easily doable with a wrapper class of some kind to regulate access. – ApproachingDarknessFish Nov 14 '12 at 05:13
  • @dreamcrash you will still have to add code to manually grow the first dimension by adding additional lists to it when an un-populated index is accessed. – Affe Nov 14 '12 at 05:16
  • thanks for the replies. @Affe.. I just want it to grow in 1-D.. the second dimension lenght is fixed – Floose Nov 14 '12 at 05:20
  • @Affe I see you point. I was also basing in this previews thread http://stackoverflow.com/questions/6232257/2d-dynamic-array-using-arraylist-in-java – dreamcrash Nov 14 '12 at 05:20
  • @LouisWasserman: `Vector` isn't deprecated, it's just thread safe. If one doesn't need the thread safety, then it's painless to switch it out for `ArrayList` otherwise. 99% of the time though, one would use `ArrayList`. – Makoto Nov 14 '12 at 05:21
  • 1
    @Makoto: I think that's why he qualified it with "more or less". It doesn't bear the deprecated tag, but new libraries take care not to ever rely on it (favouring the `List` interface 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. – Mark Peters Nov 14 '12 at 05:39
  • Yup. Not only is `Vector` synchronized when you usually don't need it; it's often synchronized in the _wrong way_ -- it's more useful to synchronize entire groups of operations than to synchronize each operation individually, for which `Lists.synchronizedList(ArrayList)` is more useful anyway. Like I said -- "more or less deprecated." – Louis Wasserman Nov 14 '12 at 16:46

5 Answers5

1

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.

Mark Peters
  • 80,126
  • 17
  • 159
  • 190
  • Well, basically, Im just accepting a bunch of user values.. a matrix if you will, and i dont know the size of the matrix.. i just want my array to be able to hold enough values and not run of size.. since its a matrix.. im opting for 2-D – Floose Nov 14 '12 at 05:25
  • 1
    @user1767157: A sparse matrix like this is probably your best bet then. – Mark Peters Nov 14 '12 at 05:26
1

You can use ArrayList which is equivalent to dynamic array.

ArrayList<ArrayList<Integer>> aDynamicArray = new ArrayList<ArrayList<Integer>>(2);
aDynamicArray.add(new ArrayList<Integer>());
aDynamicArray.add(new ArrayList<Integer>());

Now you can use you for loop as following:

int [] [] x = new x [2] [100];
for i=0 to 1 
   for j=0 to 99
       aDynamicArray.get(i).add(x[i] [j]);

EDIT:

if i wanted to access x[2] [3] , how would i do that in the arraylist?

x[2][3] means value at 3rd row and 4th column. So, Fisrt line of code will change as follows: (to accomodate 3 rows)

ArrayList<ArrayList<Integer>> aDynamicArray = new ArrayList<ArrayList<Integer>>(3);
for(int i=0; i<3, i++)
{
    aDynamicArray.add(new ArrayList<Integer>());
}

then following line will give you access to x[2][3]:

aDynamicArray.get(2).get(3);
Azodious
  • 13,752
  • 1
  • 36
  • 71
  • Why is it required to grow it in both the directions? Where did OP mention it? – Azodious Nov 14 '12 at 05:31
  • OP mentioned in comments: `thanks for the replies. @Affe.. I just want it to grow in 1-D.. the second dimension lenght is fixed.` – Azodious Nov 14 '12 at 05:33
  • Ah, sorry about that, expected to see that in the question. However, I then have to comment that using an array of a generic type is not (well) supported in Java. You're stuck using the raw type, which should never be done in new code. – Mark Peters Nov 14 '12 at 05:35
  • Thanks, So the size of the arraylist is just the number of rows i want ? is it the maximum value of i in a[i] [j]? – Floose Nov 14 '12 at 05:48
  • Yes, your understanding is correct but terminiology is not.The first line of code defines an `array` of size `two` that can hold two arraylists. – Azodious Nov 14 '12 at 05:53
  • sorry about that.. dont you mean array of size 100, that can hold two arraylists? – Floose Nov 14 '12 at 05:55
  • 1
    Nope, array of size two. i.e. two indexes. and each index holds an `ArrayList` and each `ArrayList` holds as many `int`s required. – Azodious Nov 14 '12 at 05:59
  • but i want to vary the indexes at run time...by second dimension i meant the 90 in x[100] [90].. hmm.. i ll find a workaround.. a final question, if i wanted to access x[2] [3] , how would i do that in the arraylist? – Floose Nov 14 '12 at 06:01
  • 1
    x[2][3] means, 3rd row and 4th column. it means in place of creating an array with 2 indexes, you should create with 3. Check the edited answer. – Azodious Nov 14 '12 at 06:03
  • @Azodious: I'm sorry if I wasn't clear. I was trying to say you *can't* do `new ArrayList[3]` as it's a compile error in Java. You *can* do `new ArrayList[3]` (the raw type) but shouldn't because you shouldn't use raw types in new code. Therefore this approach, mixing arraylists and arrays, is not a great approach. An `ArrayList>` would be better. – Mark Peters Nov 14 '12 at 06:24
1

Unfortunately, Java has neither 2D arrays nor 2D growing vectors.

It has array of arrays or vector of vectors.

In your example, you created 1D vector of Objects:

Vector x= new Vector();

is similar to growing array of type Object[] x

So, when you do

y.addElement(x[i][j]);

Java does "boxing", i.e. it does

y.addElement(new Integer(x[i][j]));

Since you added 100x100 elements into 1D array, you will need to calculate location yourself

y.get(i*numcols+j)

So, to avoid all this, use vector of vectors like example below. The example copies newly fixed size array into vector of vectors:

   // creates fixed size 2D array with zeros
    int [] [] x = new int [50][50]; 

    // creates empty vector of vectors of integers
    // y is of type Vector<Vector<Integer>>
    // y.get(row) is of type Vector<Integer>>
    // y.get(row).get(col) is of type Integer
    Vector<Vector<Integer>> y = new Vector<Vector<Integer>>(); 

    // set the size of vector of vectors (number of rows)
    // each row will be null for now
    y.setSize(x.length);

    // enumerating rows
    for(int row=0; row<x.length; ++row) {

        log.info("row {}", row);

        // assign empty vector for row
        y.set(row, new Vector<Integer>());

        // set row size (number of columns)
        y.get(row).setSize(x[row].length);

        // enumerating columns of current row
        for(int col=0; col<x[row].length; ++col) {

            // setting the value for a cell
            y.get(row).set(col, x[row][col]);

        }
    }
Dims
  • 47,675
  • 117
  • 331
  • 600
0

In java would be something like:

int [][] x = new int [100] [100]

ArrayList <Integer> y = new ArrayList();

y.add(some number);

More information about Arraylist

Java let you have a collection compose by different data types. For Example

ArrayList<Object> list = new ArrayList<Object>();
list.add(1);
list.add("Java");
list.add(3.14);

Thus you can also use ArrayList of ArrayList and so on.

dreamcrash
  • 47,137
  • 25
  • 94
  • 117
0

If you know the size of array (you have mentioned as 99), you can use int[][] intA = new int[100][100] and If you are familiar in java, you can implement your own Growing int[][] by monitoring array size when adding element.

Assume you are adding last element intA[99][99] = someInt at this time you can create new array int[][] newIntA = new int[intA.length+25][100]; then you need to copy content of existing intA array to newIntA

or you can use ArrayList<ArrayList<Integer>> to add your values or use ArrayList[] its your choice.

vels4j
  • 11,208
  • 5
  • 38
  • 63