We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpSyntax Questions › create and destroy objects in arrays
Page Index Toggle Pages: 1
create and destroy objects in arrays (Read 1618 times)
create and destroy objects in arrays
May 7th, 2007, 3:45pm
 
I've recently restarted programming with Processing and am currently tackling OOP. I've been looking all over the board (including ALPHA) for an answer to my questions, but haven't found anything satisfactory, or maybe I just don't know the right keywords yet.

I have an array of objects. Every time the mouse is Pressed, a new object is added to the array. This works fine. Now, I want the objects to do their thing, and meeting a certain condition be deleted from the array.

Is there a way an object can request to be deleted from the list it's being held in?
How does an object know its own address? Do I have to tell it, whenever I create a new one?

Then there's the problem, that if the objects are deleted irregularly the array will have "holes".

If I know that I won't have more than 20 objects on screen at the time, does it make sense to create an array with a set size (20), and find the empty positions for new objects?
Or can I just happily increment the positions, having new objects be positioned at maybe array[52718]? What's a reasonable max. length for an array? Or can it (theoretically) be infinitely big in length? Would this lead to slow-downs?

Anyone have any pointers on how I should best go about this problems?
Thanks in advance.
Re: create and destroy objects in arrays
Reply #1 - May 7th, 2007, 7:16pm
 
Hi dek,
Arrays have a fixed size; what you want to use is a resizeable data structure, such as an ArrayList. This will let you add/remove items as you please, without leaving holes.

You can remove objects from the ArrayList by index or by value.

http://java.sun.com/j2se/1.4.2/docs/api/java/util/ArrayList.html

Cheers,
-robin
Re: create and destroy objects in arrays
Reply #2 - May 7th, 2007, 8:57pm
 
Robin,

Thanks for your reply. I came across ArrayList earlier during my research, and had a look at the documentation.
But reading about "synchronization" and "amortized time cost", I had the slight feeling, that I probably should stick Processing a little more, before I try my luck with full on Java. One step at a time Smiley (Unless you convince me, that arrayList is less of a hassle)

If I try to stay within Processing's functionality,
Is changing the array length using append() not a good solution?
Is it impossible to delete an object by index and trying to manage the resulting "holy" array?

cheers,
Greg
Re: create and destroy objects in arrays
Reply #3 - May 7th, 2007, 9:16pm
 
Hi Dek,
ArrayLists are actually easier to use than arrays in most cases. Here's an example for storing Strings:

import java.util.ArrayList; // put at start of your file

void setup()
{
 ArrayList  v = new ArrayList();
 v.add( "one" );
 v.add( "two" );
 v.add( "three" );
 v.add( "four" );

 for (int i=0; i<v.size(); i++)
   println(v.get(i));

 // will print:
 // one
 // two
 // three
 // four

 v.remove(1);

 for (int i=0; i<v.size(); i++)
   println(v.get(i));

 // will now print:
 // one
 // three
 // four

 v.remove("three");

 for (int i=0; i<v.size(); i++)
   println(v.get(i));
   
 // will now print:
 // one
 // four
}

A note: ArrayLists can't store primitive types (like int, float, etc). You'll have to store their fancy versions (Integer, Float, etc) and get the primitive value stored within.

Cheers,
-robin
Re: create and destroy objects in arrays
Reply #4 - May 7th, 2007, 10:35pm
 
Robin, thanks for the code! I really appreciate your effort.
Indeed, this does look simple. For Strings. I have tried to rewrite it to work with objects (whose handling I'm yet far from confident with), and that's a total no-go.

I read up on int vs. Integer, but all I learned from it, is that my code-fu isn't nearly where it should be.
I also found this thread, with Fry's reasoning contra ArrayList.

It's kind of a dilemma. ArrayList seems to do the job nicely, but it seems inaccessible for me right now. On the other hand, Processing's array handling seems to be restricted in what I want to do. Damn.

Fry to the rescue




Re: create and destroy objects in arrays
Reply #5 - May 7th, 2007, 10:43pm
 
Hi Dek,
I don't think this is a matter for Fry, it's just a reality of programming -- arrays are a fixed size, in Processing or in plain Java. The speed issue that Fry refers to is due to having to wrap primitives in an Object that can be stored. It's not optimal, but I doubt you'll notice worse performance in a simple application.

You say you're trying to store objects; Strings are objects too. What are you trying to store? If you're trying to get at the items in your ArrayList, you need to do something called "Casting" to the correct type of object. Calling myArrayList.get(5) will return an instance of the class called Object, which is the grandaddy of all Java objects.

If you know for a fact that what you put in the ArrayList is actually a Turnip object, or anything else, you have to do this:

Turnip t = (Turnip) myArrayList.get(5);

If it's a String you've stored, do this:

String s = (String) myArrayList.get(5);

Then you can call methods on your Turnip.

Cheers,
-robin
Re: create and destroy objects in arrays
Reply #6 - May 7th, 2007, 11:33pm
 
aha! We're making progress.

I managed to rewrite the code to work using ArrayList and it does what I managed to do in my initial sketch. But now I want to delete objects.

Let's say I have a timer and when that runs down to 0 the object is deleted. I'm imagining, that I can call myArrayList.remove(position) from within the object that's going to be deleted, right?
But how can an object know what position it's at? Do I have to tell it, when it's created? That seems a bit unclean. Is there an equivalent to ActionScript's "this." in Java? The object should be able to tell the ArrayList: "remove me from the position I'm stored at."

I already feel 0.5%  less n00b.
Re: create and destroy objects in arrays
Reply #7 - May 8th, 2007, 1:46am
 
Hi Dek,
One of the great things about ArrayLists is that you don't need to know the object's position (AKA index) in the list. Check out the String example I posted earlier; you can just do:

myList.remove("three");

Or:

Turnip t = new Turnip();
myList.add(t);

and to remove it:

myList.remove(t);

Cheers,
-robin
Re: create and destroy objects in arrays
Reply #8 - May 8th, 2007, 9:41am
 
For those concerned with speed (I am a speed whore! process speed that is, not the illegal substance) I did a crude test myself a few weeks back to see which who wins out:

Note that I've built my own "Object" (in this case "Entity") class with its own array handlers. I wanted to see if arrays by themselves can be faster dynamically, or if built-in ArrayLists are faster.

The answer somewhat surprised me....

Code:


...

static int resolution = 1000000;
void draw(){
EntityList entityList = new EntityList();
ArrayList arrayList = new ArrayList();
Vector vector = new Vector();

float timer = 0;

Entity entity = new Entity();

println("adding to array");
timer = millis();
for(int i=0; i<resolution; i++){
entityList.push( entity );
}
timer = (millis() - timer);
println( timer );
timer = millis();
for(int i=0; i<resolution; i++){
arrayList.add( entity );
}
timer = (millis() - timer);
println( timer );
timer = millis();
for(int i=0; i<resolution; i++){
vector.add( entity );
}
timer = (millis() - timer);
println( timer );

try{ Thread.sleep(1000); } catch(Exception e){;}

println("traversing array");
timer = millis();
for(int i=0; i<resolution; i++){
Entity e = entityList.getEntity(i);
}
timer = (millis() - timer);
println( timer );
timer = millis();
for(int i=0; i<resolution; i++){
Entity e = (Entity) arrayList.get(i);
}
timer = (millis() - timer);
println( timer );
timer = millis();
for(int i=0; i<resolution; i++){
Entity e = (Entity) vector.get(i);
}
timer = (millis() - timer);
println( timer );
}

// Entities can be anything.
// They can be a process, event, game timer, particle, space ship.
// All entities will have a think() in which they do computational work.


class Entity{
.....






From my experiment:

Code:

// Test results...
//
// adding to array
// entitylist: 81.0 ms
// arraylist: 45.0 ms
// vector: 158.0 ms
//
// traversing array
// entitylist: 10.0 ms
// arraylist: 14.0 ms
// vector: 58.0 ms
//
// holy shit...
// EntityList's only advantage is that it's slightly better than arraylist for traversal.
// Other than that, arraylists seem pretty damned fast.
// Vector is a slow bugger.



Array traversal via normal good ol fashioned arrays is simply faster, by a tiny margin.

When adding objects though, ArrayLists still beat out my "optimized" version of object insertion. My version also includes "smart" dynamic sizing so it multiplies its capacity only when it exceeds some set limit.

Short conclusion is that if you need a list in which the contents are constantly changing, then ArrayLists are still better despite the fact that you COULD implement your own version.

When you have massive amounts of data and need to traverse them all, and the list is mostly unchanging, then arrays are the obvious choice. The reason that ArrayLists are slightly slower than normal arrays is because of the extra cast that you need to make in order to get your object back out.

The sad thing is I used to always use Vectors without knowing the existence of ArrayList. Imagine my delight discovering I could multiply my performance simply by doing a find/replace!

A word of warning, since the OP brought it up:

One would choose Vectors when dealing with Threads and any unsynchronized behavior. However, if you don't expect your list to change asynchronously, then by all means use ArrayLists.
Re: create and destroy objects in arrays
Reply #9 - May 8th, 2007, 9:47am
 
Oh, if anyone's interested in the code for the custom entity list, it looks like

Code:

// Entities can be anything.
// They can be a process, event, game timer, particle, space ship.
// All entities will have a think() in which they do computational work.

class Entity
{
Entity(){}
public void think(){}
}

// Entity Lists contain an array of entities.


class EntityList
{
private Entity entities[] = new Entity[ initialSize ];
private int currentIndex = 0;

private static final int initialSize = 16;

public EntityList(){};

// ENTITY CALLBACK METHODS ////////////////////////////////////////////////////////////
public void listThink(){
// if list is less than fourty, ues normal loop
if( entities.length < 40 ){
for(int i=0; i<currentIndex; i++){
entities[i].think();
}
}
else{
try{
for(int i=currentIndex-1; ; --i){
entities[i].think();
}
}
catch(Exception e){;}
}
}

// PUBLIC LIST METHODS ////////////////////////////////////////////////////////////
// add an entity to the end of the list
public void push(Entity e){
entities[ currentIndex ] = e;
currentIndex++;
if(currentIndex >= entities.length)
expandList();
}

// remove an entity from the end of the list
public void pop(){
entities[ currentIndex ] = null;
currentIndex--;
if(currentIndex < (int) entities.length >> 1)
shrinkList();
}

// clear the list
public void clear(){
entities = new Entity[ initialSize ];
}

// get an entity from the list
public Entity getEntity(int index){
if(index > currentIndex)
return null;
if(index < 0)
return null;
return entities[ index ];
}

// return the list for use
public Entity[] getList(){
Entity sizedList[] = new Entity[currentIndex];
System.arraycopy(entities, 0, sizedList, 0, sizedList.length);
return sizedList;
}

// unfinished.
public Vector createVectorList(){
return new Vector();
}

// returns the length of used parts of the array
public int length(){
return currentIndex;
}

// returns the current size of the array
public int size(){
return entities.length;
}

// PRIVATE LIST METHODS ////////////////////////////////////////////////////////////
private void expandList(){
Entity newList[] = new Entity[ entities.length << 1 ];
System.arraycopy( entities, 0, newList, 0, entities.length );
entities = newList;
}

private void shrinkList(){
if( entities.length <= 1 )
return;
Entity newList[] = new Entity[ entities.length >> 1 ];
System.arraycopy( entities, 0, newList, 0, newList.length );
entities = newList;
}

// not currently used but later when we write removal or insertion routines we'll want to complete these
private void removeViaIndex(int i){
Entity newList[] = new Entity[ entities.length - 1];
System.arraycopy(entities,0, newList,0, i);
System.arraycopy(entities,i+1, newList,i, newList.length-i);
entities = newList;
}

}

Re: create and destroy objects in arrays
Reply #10 - May 8th, 2007, 11:14am
 
Code:

myList.remove(t);


How difficult can it be?
I'm posting my code to clarify things. It works, EXCEPT the deleting of the linedrawing-Objects.

Code:

import java.util.ArrayList;

ArrayList lines = new ArrayList();

// check if ArrayList is empty
boolean check = false;

void setup() {
 size(400,400);
 background(255);
}

void draw() {
 // only start drawing objects, when at least one exists
 if (check == true) {
   for (int i=0; i < lines.size(); i++) {
     Line l = (Line) lines.get(i);
     l.go();
     l.render();
   }
 }
}

void mousePressed() {
 // extend arrayList with new object to array  
 lines.add( new Line(color(0), mouseX, mouseY, random(50) ) );
 check = true;
}


class Line {

 // Instance variables
 int timer;
 float xpos;
 float ypos;
 color c;

 // Construtor
 Line(color _c, float xp, float yp, int _timer) {
   timer = _timer;
   xpos = xp;
   ypos = yp;
   c = _c;
 }

 // Methods
 void render() {
   if (timer == 0) {    
     // *************************************************  
     // delet this object from ArrayList, how?
     // something like lines.remove(thisObject)?
     // or am I going at it in the wrong way.
     // *************************************************
   }
   stroke(c);
   point(xpos, ypos);
   timer--;
 }

 void go() {
   xpos++;
 }
}



Am I at least on the right track? Or does anyone see a flaw in my thinking?

cheers,
Greg

Btw, how can I make my syntax color-coded on this board?
Re: create and destroy objects in arrays
Reply #11 - May 8th, 2007, 2:09pm
 
this what you are looking for?
Code:

if (timer == 0) {
lines.remove(this);
return;
}


to color your code use the tool in processing:
Tools->Copy For Discourse

F
Re: create and destroy objects in arrays
Reply #12 - May 8th, 2007, 2:14pm
 
fjen's code should do the trick.

One additional comment: instead of using your boolean 'check' variable, just try:

if(lines.size() > 0)
{
}

Cheers,
-robin
Re: create and destroy objects in arrays
Reply #13 - May 8th, 2007, 3:09pm
 
it works!

senior, you the man!
fjen, sweet!
mflux, you rock!
Processing board, you rule!
me, very happy!


Here's the final code as a reference.

Quote:


// put this at the beginning, if you want to work with arrayLists
import java.util.ArrayList;

//create empty arrayList
ArrayList lines = new ArrayList();

void setup() {
 size(400,400);
 background(255);
}

void draw() {
 // only start drawing objects when arrayList isn't empty
 if (lines.size() > 0) {
   for (int i=0; i < lines.size(); i++) {
     Line l = (Line) lines.get(i);
     l.grow();
     l.render();
   }
 }
}

void mousePressed() {
 // add new object to arrayList
 lines.add( new Line(color(0), mouseX, mouseY, int(random(20, 100))) );
}

// ****************

class Line {

 // Instance variables
 color c;
 float xpos;
 float ypos;
 int timer;

 // Construtor
 Line(color _c, float xp, float yp, int _timer) {
   c = _c;
   xpos = xp;
   ypos = yp;
   timer = _timer;
 }

 // Methods
 void render() {
   
   if (timer == 0) {  
       destroy();
   }
   stroke(c);
   point(xpos, ypos);
   timer--;

 }

 void grow() {
   xpos++;
 }
 
 void destroy() {
   // delet this object from arrayList
   lines.remove(this);
 }
}

Page Index Toggle Pages: 1