ArrayList of ArrayLists (dynamic 2D array) of custom class

Hello everybody!
So, I just tried to create a ArrayList of ArrayLists with a custom class.
However I am a bit stuck on how to read from / write to certain elements in this ArrayList thing.

class Event { //The class for each element in the array //Just some example variables for now ... int ExampleInt; String ExampleString; }

Event DefaultEvent;

//An EventString is a collection of Events
ArrayList EventString = new ArrayList();
//The EventTable is a collection of EventStrings
ArrayList EventTable = new ArrayList ();

void PrintEventData (int EventString, int EventID)
{
//Prints event data
//“Copy” the specified element into a temporary variable for easier printing
Event EventToPrint;
EventToPrint = EventTable.get(EventString).get(EventID);

print("Example Int = ");
print(EvenToPrint.ExampleInt);
print("Example String = ");
print(EvenToPrint.ExampleString);
print("\n");

}

This is the error that the compiler gives me:
Cannot convert from Object to EventSimulator.Event

I am pretty sure that this is about the following line:
EventToPrint = EventTable.get(EventString).get(EventID);

But this does make no sense!
The type of what the EventTable.get(EventString).get(EventID) returns is Event, right? And the type of EventToPrint is Event, so why is this not working?
How can I get this to work?

array list of array lists of vectors:
ArrayList<ArrayList<PVector>> name = new ArrayList<ArrayList<PVector>>();
how to use it?

use

ArrayList<ArrayList<PVector>> points = new ArrayList<ArrayList<PVector>>();
ArrayList<PVector> group = new ArrayList<PVector>();
loadPoints(); //a custom function (name it anything) to add random points to group() ArrayList.
points.add(group);

//how to access information of points > group 
//(what used to be the group ArrayList, which is inside of the <point> ArrayList.
points.get( <ArrayList id> ). get(<item id>);
//if you don't know, ArrayList<PVector<.get(<id>) acts exactly the same as a PVector. similary, 
//ArrayList<ArrayList<PVector>>.get(<id>) acts the same as ArrayList<PVector>. Therefor, you can do
//points.get(<id>).get(<id>);

I am not too good at explaining so if you have any questions / want some examples, just say so.

Have a nice day!

that’s right.

As stated in the reference you have to either cast the type from Object to your class OR as has been shown, tell the ArrayList it’s type using ArrayList<Classname>

2 Likes

When creating an ArrayList without specifying the type that it’s going to hold, it’s the same as saying :

ArrayList<Object> EventString = new ArrayList<Object>();

Because every class inherits from the Object class.

Therefore you would need to cast to your class before calling a method :

EventToPrint = ((Event) EventTable.get(EventString)).get(EventID);

See this thread :

But you should always specify the type to the ArrayList because it’s going to indicate to the compiler that this array is only storing instances of class (or derived from) Event for example, therefore raising errors when compiling.

As @CodeMasterX said, you can create it like this :

ArrayList<Event> EventString = new ArrayList<Event>();
ArrayList<ArrayList<Event>> EventString = new ArrayList<ArrayList<Event>>();

But since Java SE 7, you can use the diamond notation as stated in the documentation :

In Java SE 7 and later, you can replace the type arguments required to invoke the constructor of a generic class with an empty set of type arguments (<>) as long as the compiler can determine, or infer, the type arguments from the context. This pair of angle brackets, <>, is informally called the diamond .

ArrayList<ArrayList<Event>> EventString = new ArrayList<>();

Thus this is not supported in the Processing IDE, it says : :cry: :cry:

unexpected token: >
3 Likes

Instead of doing this (which is hard to read for a human) I recommend to
move the 2nd ArrayList into a class.

//The EventTable is a collection of EventStrings
ArrayList<EventTable> eventTables = new ArrayList(); // of class EventTable

And the class

class EventTable{

    //An EventString is a collection of Events
    ArrayList<EventString> eventStrings  = new ArrayList(); // of class EventString 


} //class

class EventString{

    String event = "";  // String


} //class

2 Likes

But I did state what type the arraylist uses:

//An EventString is a collection of Events
ArrayList < Event > EventString = new ArrayList();
//The EventTable is a collection of EventStrings
ArrayList < ArrayList > EventTable = new ArrayList ();

And I still get that error.
Ok, this is weird.
I just realized that this text posting thing on this website does not print the < > inside of my copy&pasted code unless there is some space around it!

You used array list in a wrong way.
use

ArrayList<Event> EventString = new ArrayList<Event>();

That is what I used!
I forgot to edit the < > so that they would show up.

//An EventString is a collection of Events
ArrayList < Event > EventString = new ArrayList < Event > ();
//The EventTable is a collection of EventStrings
ArrayList < ArrayList > EventTable = new ArrayList < ArrayList > ();

You still have to define the ArrayList inside. You need to use
ArrayList<ArrayList<Object>> EventTable = new ArrayList<ArrayList<Object>>()

2 Likes

Thanks!
I think that works!

2 Likes

: D

Well as long as it works! Have a nice day!

1 Like

@ProgrammingN00b

Note that it’s better to write it with the type specified :

ArrayList<ArrayList<Event>> EventString = new ArrayList<ArrayList<Event>>();

Because if you get an element from the array, it will be of type Object and you have to explicitly cast it, it will work but you are going to have errors :

class Event {
  int ExampleInt = 0;
}

ArrayList<Object> events = new ArrayList<Object>();

events.add(new Event());

Event e = events.get(0); // -> cannot convert from Object to Event

Event e2 = (Event) events.get(0); // -> it works!

Also the issue is that you can accidentally add any instance of an object to the array which can lead to bugs :

ArrayList<Object> events = new ArrayList<Object>();

events.add(new Integer(0)); // -> Works but it's not what you want!

println(event.get(0).ExampleInt); // -> Error it's not an Event instance !!
2 Likes

Ok, now that that works, that leads to the next question:
How do I “write” values to this “ArrayList of ArrayLists”?

“Getting” them is easy:

//Create a temporary storage variable of the type Event
Event EventToPrint;

//“Copy” the stuff that should be printed from the actual ArrayList thing into the temporary variable
EventToPrint = EventTable.get(EventString).get(EventID);

//Print the varible(s) of the temporary variable that you want to print
print(EventToPrint.ExampleString);

For example, I want to write the value of DefaultEvent.ExampleString to EventTable[0][0], how would this be done?
So don’t replace the whole object stored at [0][0], just access one of its “member variables” (if that is the correct term).

Hi @ProgrammingN00b ,

Since you are struggling with ArrayList and dimensional arraylists, I would recommend you to take a look at the following links

Useful Links

ArrayList of ArrayList in Java - GeeksforGeeks
https://www.baeldung.com/java-multi-dimensional-arraylist
https://www.youtube.com/watch?v=9tBxJoQF74E&ab_channel=BroCode

I hope it helps :slight_smile:

4 Likes

Thanks for that, but I already did some searching around myself and came across those websites that you linked.
I know how to get or set regular types like string, int, …
What I struggle with is getting or setting custom classes or specifically the member variables of custom classes.

You can do it like this :

// -> Get the first element of the first array
Event event = eventTable.get(0).get(0);

// -> Change it's value
event.defaultEvent.exampleString = "random string";

As ArrayList and List in general don’t have the [] operator, you need to chain the .get() calls in order to do it.

Note that you should use the camel Case notation for variables and member variables to differentiate them from class names so it’s more clear :wink:

2 Likes

Ok, but how would I “write back” that Element into the ArrayList so just “exampleString” gets changed and no other member variable?

Get it “out of the array” into a temporary variable, change only the things I want to change, then overwrite the “original” element in the array with the “updated” temporary variable, right?

And yes, I know that there is no [] to interface with arraylists here, I just used that to make it more “understandable” for everybody.
(Since the ArrayList thing obviously tries to be the “vector” we have in C++)

Ok, if you know C++ then think of Java variables that stores object as a reference to the actual memory location of the allocated object.

It means that if I assign a variable holding an object to another variable, then the new variable is going to point (reference) the same memory location :

class Value {
  int value = 0;
}

Value v1 = new Value();
println("v1 : " + v1.value);

Value v2 = v1;
println("v2 : " + v2.value);

v2.value = -5;
println("v2 value after change " + v2.value);
println("v1 value after v2 change " + v1.value);

Prints :

v1 : 0
v2 : 0
v2 value after change -5
v1 value after v2 change -5

Because v2 points to v1 therefore when you change v2, you change v1. That’s why we have the notion of copy in Java (and deep copy) in order to duplicate entire objects.

So storing the result of eventTable.get(0).get(0) to a variable is just storing a reference to that element! :wink:

2 Likes

Ooooohhhhh …
Well, that is weird …
So if I use v1 = v2, the value of v1 will ALWAYS be the same as v2, no matter what. The will be “linked” forever … ?
So to just “copy” the value from one variable to another I would use copy()?
Do you have any link to a documentation for that because I can’t find it in the processing language reference …