开发者

Java - multidimensional array of vectors of generic type

Imagine, if you will, a 10x10x10 cube made out of 1x1x1 bricks. Each brick must be accessable by an x,y,z coordinate. For each brick I also need to store a list of names of who own that 'brick'.

As efficiency is an absolute must, I came up with the following idea - A 3d array of vectors. note- I have made a class which stores a name, and other info (called person)

//declaration
    protected Vector<person>[][][] position;

I think I must then allocat开发者_JS百科e memory to the pointer position. I have tried this

position = new Vector<person>[10][10][10]; 

But am getting an error 'Cannot create a generic array of Vector' I am only familiar with C++ and Java is new to me. I understand java does not like declaring arrays with generic type? Does anyone know how I can get around this problem?

Cheers


No need to complicate things that much! You know the size of the array (10:10:10), so there's no need to go for vectors or other stuff for the bricks. Try using array of objects:

Class Brick {
 public Brick(int x, int y, int z){

   this.x=x;
   this.y=y;
   this.z=z;

   owners = new ArrayList <String> ();
 }

 List<String> owners;

 int x, y, z;  //every brick "knows" its position - you might not need it

} 

Code for creating the array:

Public Class Main {
  .....

 Brick Cube[][][] = new Brick[10][10][10];
 for (int x=0; x < 10; x++)
   for(int y=0; y < 10; y++)
     for(int z=0; z < 10; z++)
     {
       Cube[x][y][z] = new Brick(x, y, z);
     }

//adding an owner to a brick:
 Cube[0][0][0].owners.add("Owner");
.....
}

Keep OOP in mind - It makes things much easier!

TODO: add getters/setters


If you did want to go down the route of using a List structure rather than arrays, this should be enough to get you started. This is based off of what @FrustratedWithFormsDes said, but I included the initilization code since it's hard to get the syntax right.

public class Person {
}

class PeopleStorage {

    ArrayList<ArrayList<ArrayList<Person>>> data;

    public PeopleStorage(int size) {

    this.data = new ArrayList<ArrayList<ArrayList<Person>>>(size);

    for (int i = 0; i < size; i++) {
        ArrayList<ArrayList<Person>> inner = new ArrayList<ArrayList<Person>>(
            size);
        data.add(inner);
        for (int j = 0; j < size; j++) {
        ArrayList<Person> inner2 = new ArrayList<Person>(size);
        inner.add(inner2);
        for (int k = 0; k < size; k++) {
            inner2.add(new Person());
        }
        }
    }
    }

     public Person get(int index1, int index2, int index3)
     {
      //check indices against size, throw IllegalArgumentException here
     return data.get(index1).get(index2).get(index3);
     }

     public void set(Person person, int index1, int index2, int index3)
     {
     //check indices against size, throw IllegalArgumentException here
     data.get(index1).get(index2).set(index3, person);
     }
}


What you are trying to do is impossible in java, because there is no operator overloading (like in C++). In short the [] operator in Java is defined only for arrays and cannot be overloaded. Therefore the only way to access elements inside Vector/ArrayList is through the get() method (or through an Iterator or couple other methods, but you get the picture). Analogically you cannot define multi-dimensional ArrayList that way. What you should do is ArrayList<ArrayList<ArrayList<Person>>> people = new ArrayList<ArrayList<ArrayList<Person>>>() and then go and initialize all the internal arrays with nested loops or whatever you wish. It looks a little bit ugly, and since ArrayList/Vector is a dynamic collection adding for example a new element at the first array would require you to initialize the two nested arrays as well. So you might be better off in design terms with writing some form of a wrapper for that class in order to isolate that logic there.

The difference between ArrayList and Vector in Java is that vector is synchronized (therefore slower) and in the default growth pattern (Vector doubles its size, while ArrayList grows by 50%). Otherwise they are pretty much identical in functionality and complexity of operations.


I think you will want to use an ArrayList instead of a vector. I'm a bit rusty on this, but from what I recall, mixing arrays and generic containers is not a good idea.

You could try this:

position = new ArrayList(10)<ArrayList(10)<ArrayList(10)<Person>>; 

but it's rather ugly to read. Accessing data is like this:

person = position.get(1).get(3).get(6); //get someone at x=1, y=3, z=6

Beware I don't have the chance right now to compile this and see if it actually works, so you will want to read the docs on ArrayList but I think this is the direction you could go in...


Update: jhominal has pointed out some news that I forgot, I don't have a Java compiler on hand to verify this, but if you try this solution, take a look at what he says as well.


Note: This is more of an explanation of why generic arrays don't work in Java rather than an answer to your actual question.

Effective Java 2nd Edition deals with generic arrays on page 119 of Chapter 5 (PDF).

Why is it illegal to create a generic array? Because it isn't typesafe. If it were legal, casts generated by the compiler in an otherwise correct program could fail at runtime with a ClassCastException. This would violate the fundamental guarantee provided by the generic type system.

This is because Java Generics only have types at compile time and insert the appropriate casts so specific operations work at runtime.

The easiest solution to this problem is likely the one Ed.C provided.


I would also go with the object answer by Ed.C, but this seems to work:

@SuppressWarnings("unchecked")
protected Vector<Person>[][][] position = new Vector[10][10][10];

ie, you skip the diamond on the right.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜