2

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 allocate 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

John
  • 31
  • 1
  • 2

6 Answers6

5

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

Ed.C
  • 798
  • 1
  • 5
  • 17
2

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);
     }
}
Greg Case
  • 3,052
  • 1
  • 17
  • 17
0

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.

Community
  • 1
  • 1
FrustratedWithFormsDesigner
  • 25,116
  • 30
  • 128
  • 188
  • I briefly tried using an ArrayList. However, I think I had the same problem with complaints about a generic type. I will give that link a read though, thanks. – John Oct 22 '10 at 18:53
  • You're right that mixing arrays and generics isn't possible, however ArrayList vs Vector doesn't really matter. – Steven Schlansker Oct 22 '10 at 19:05
  • 1
    `ArrayList>> cube = new ArrayList>>();` – shoebox639 Oct 22 '10 at 19:18
  • @shoebox639: Thanks for testing! :) – FrustratedWithFormsDesigner Oct 22 '10 at 19:32
  • The code that you wrote to create the array will not work. You need to call `new ArrayList>>();` first, and then fill each index with a `new ArrayList>();`, etc. – Jean Hominal Oct 22 '10 at 19:37
  • Item 25 in Effective Java 2nd Edition is "Prefer lists to arrays" (on pages 119-123). This is because arrays do **not** work well with generic collections. PDF of this chapter here: http://java.sun.com/docs/books/effective/generics.pdf – Powerlord Oct 22 '10 at 19:43
0

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.

vstoyanov
  • 831
  • 5
  • 14
0

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.

Community
  • 1
  • 1
Powerlord
  • 82,184
  • 16
  • 119
  • 164
-1

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.

Avall
  • 770
  • 1
  • 4
  • 13