Loading...
Logo
Processing Forum
Hi, 
I'm searching to make a function who has 3 parameters : String, ArrayList, Class ;
the goal of it is to search inside the ArrayList if an instance has the name specified in String parameter. 
I've got an error : the Class parameter don't replace the Class name inside the function.

thanks a lot. 

Copy code
  1. IntDict isNAMEinsideCLASS(String name, ArrayList itemList, Class theClass) {
  2.   IntDict toReturn = new IntDict();
  3.   int nmbInequality = 0;
  4.   for (int i= 0; i<itemList.size(); i++) {
  5.     theClass item = itemList.get(i);
  6.     if (item.name.equals(name)) {
  7.       toReturn.set("true", i);
  8.     }
  9.     else {
  10.       nmbInequality+=1;
  11.     }
  12.   }
  13.   if(nmbInequality == itemList.size()){
  14.    toReturn.set("false", -1); 
  15.   }
  16.   return toReturn;
  17. }

Replies(10)

Class objects? That is too much advanced for me. Anyways, some points I've spotted:

1)
To access anything from a List, like using get() method for example,
we gotta specify what we're getting at that moment.

So, if what's inside an ArrayList are Class objects, we either use a cast operator like (Class) or
declare a variable using Generics like:

IntDict isNAMEinsideCLASS(String name, ArrayList<Class> itemList, Class theClass) {

So the Java's compiler knows what's to expect from that List @ itemList.

2)
We can't use variable labels for data-type declarations as you do @ theClass item = itemList.get(i);
Only a class or interface label is valid for declarations. Besides the 8 primitive types of course.
As said, you cannot pass a type to a function and declare a variable of this type.
And if get(i) isn't of the type in theClass, then you would get an exception (ClassCastException).
This kind of "dynamic type" programming isn't canonical in Java.

Let's try to do it the Java way, although you don't give the motivation behind your function.
Ah, I have a description of your goal " the goal of it is to search inside the ArrayList if an instance has the name specified in String parameter."

Let's suppose your array list hold objects of various types, but all of them have a name field.
Then, you can declare an interface:
Copy code
  1. interface HasName
  2. {
  3.   String getName();
  4. }
Then, you can make all your classes to implement this interface:
Copy code
  1. class SomeStuff implements HasName
  2. {
  3.   String name;
  4.   // Other declarations
  5.   // Other methods
  6.   // Method imposed by the interface:
  7.   public String getName()
  8.   {
  9.     return name;
  10.   }
  11. }
Then, your array list can be declared as follows:
Copy code
  1. List<HasName> namedStuff = new ArrayList<HasName>();
And your function would look like:
Copy code
  1. IntDict isNAMEinsideCLASS(String name, ArrayList<HasName> itemList) {
  2.   IntDict toReturn = new IntDict();
  3.   int nmbInequality = 0;
  4.   for (int i= 0; i<itemList.size(); i++) {
  5.     HasName item = itemList.get(i);
  6.     if (item.getName().equals(name)) {
  7.       toReturn.set("true", i);
  8.     }
  9.     else {
  10.       nmbInequality+=1;
  11.     }
  12.   }
  13.   if(nmbInequality == itemList.size()){
  14.    toReturn.set("false", -1); 
  15.   }
  16.   return toReturn;
  17. }
Here, you made a super-type which works for all the objects you can put in the list, as long as they all implement the interface.
You can refine the concept by adding a type field, if you need.
A concrete illustration. Just for the proof of concept, I added detection of the class of the item to find.
Copy code
  1. interface HasName
  2. {
  3.   String getName();
  4. }
  5.  
  6. class SomeStuff implements HasName
  7. {
  8.   String name;
  9.   // Other declarations
  10.  
  11.   SomeStuff(String n) { name = n; }
  12.   // Other methods
  13.  
  14.   // Method imposed by the interface:
  15.   public String getName()
  16.   {
  17.     return name;
  18.   }
  19.  
  20.   public String toString() { return getClass().getName() + " " + name; }
  21. }
  22.  
  23. class OtherStuff implements HasName
  24. {
  25.   String name;
  26.   // Other declarations
  27.  
  28.   OtherStuff(String n) { name = n; }
  29.   // Other methods
  30.  
  31.   // Method imposed by the interface:
  32.   public String getName()
  33.   {
  34.     return name;
  35.   }
  36.  
  37.   public String toString() { return getClass().getName() + " " + name; }
  38. }
  39.  
  40. ArrayList<HasName> namedStuff = new ArrayList<HasName>();
  41.  
  42. int isNAMEinsideCLASS(String name, ArrayList<HasName> itemList, Class kind) {
  43.   for (int i = 0; i < itemList.size(); i++) {
  44.     HasName item = itemList.get(i);
  45.     if (item.getName().equals(name) && item.getClass().equals(kind)) {
  46.       return i;
  47.     }
  48.   }
  49.   return -1;
  50. }
  51. void setup()
  52. {
  53.   namedStuff.add(new SomeStuff("foo"));
  54.   namedStuff.add(new OtherStuff("gah"));
  55.   namedStuff.add(new SomeStuff("bar"));
  56.   namedStuff.add(new OtherStuff("bu"));
  57.   namedStuff.add(new SomeStuff("bu"));
  58.  
  59.   println(namedStuff);
  60.  
  61.   println(isNAMEinsideCLASS("gah", namedStuff, SomeStuff.class));
  62.   println(isNAMEinsideCLASS("bu", namedStuff, SomeStuff.class));
  63.   println(isNAMEinsideCLASS("bu", namedStuff, OtherStuff.class));
  64.   exit();
  65. }

whow, 
thanks a lot. 
so I have to learn about interface 

by the way : 

yes, I've got three ArrayList who hold three different Class.
and I don't manage to answer the question "what's the type of my Class ?"
this is three subclass  with their fields & methods, like this example : 
http://processing.org/examples/inheritance.html
if you can enlighten me. 

and yes, all my Class Object   have a name field. 
thank you
In the change global value with slider thread, I give another explanation about interfaces, if it can help.

I have not understood your last question.
As already mentioned, if you make your classes to inherent from a common 1,
you can put every1 inside a composite, like an Array , ArrayList , HashMap , etc.

From your own link above, there are 3 classes. But 1 of them is the "parent". The other 2 are "children".
I've made some modifications there to better illustrate the technique. Check it out:
Copy code
    final static int NUM = 3;
    final Spin[] spins = new Spin[NUM];
    
    void setup() {
      size(600, 400);
      strokeWeight(1);
    
      // instantiating 1 SpinSpots object into Array
      spins[0] = new SpinSpots(width>>1, height>>1, -.03, 0200);
    
      // Instantiting 2 SpinArm objects into Array
      spins[1] = new SpinArm(width>>1, height>>1, .01);
      spins[2] = new SpinArm(width>>1, height>>1, -.05);
    }
    
    void draw() {
      background(0300);
    
      // both SpinSpots & SpinArm
      for (Spin spin: spins)  spin.script();
    }
    
    abstract class Spin {   // Abstract Parent
      float x, y, speed;
      float angle;
    
      Spin(float xpos, float ypos, float s) {
        x = xpos;
        y = ypos;
        speed = s;
      }
    
      void update() {
        angle += speed;
      }
    
      abstract void display();
    
      void script() {
        update();
        display();
      }
    }
    
    class SpinSpots extends Spin {   // Child A
      int dim;
    
      SpinSpots(float x, float y, float s, int d) {
        super(x, y, s);
        dim = d;
      }
    
      void display() {
        noStroke();
    
        translate(x, y);
        rotate(angle);
    
        ellipse(-dim>>1, 0, dim, dim);
        ellipse(dim>>1, 0, dim, dim);
    
        resetMatrix();
      }
    }
    
    class SpinArm extends Spin {   // Child B
      SpinArm(float x, float y, float s) {
        super(x, y, s);
      }
    
      void display() {
        stroke(0);
    
        translate(x, y);
        rotate(angle);
    
        line(0, 0, height>>1, 0);
    
        resetMatrix();
      }
    }
    
okay, thanks, 
just to well understand, my question was : 
what is the *type* of an object ? 

Here's example which shows how to extract type name from arbitrary objects. There're actually to ways to represent type as "CanonicalName" and as "SimpleName" (the last one is the one you're used to think of when you make your types, the former is how Java sees class names).



Here's code for the sketch:
Copy code

  1. void setup(){
  2.   // as the sketch is a class itself, let's print it's names.
  3.   printTheClassCanonicalName(this);
  4.   printTheClassSimpleName(this); // this is also way to figure out name of your sketch.
  5.   
  6.   println();
  7.   
  8.   // now let's make our own class and try to see it's names:
  9.   MyClass myClass = new MyClass();
  10.   printTheClassCanonicalName(myClass);
  11.   printTheClassSimpleName(myClass);
  12.   
  13.   exit();   
  14. }

  15. /**
  16. * Just sample class, can be declard here or in
  17. * the separate tab. (In the sep. tab NOT ending with ".java")
  18. */
  19. class MyClass{
  20. }


  21. void printTheClassCanonicalName(Object obj){
  22.    println("Your class canoical name is: " + obj.getClass().getCanonicalName());
  23. }

  24. void printTheClassSimpleName(Object obj){
  25.    println("Your class SIMPLE name is: " + obj.getClass().getSimpleName());
  26. }


  27. void draw(){
  28. }



ps. @mloizix,  I was wondering if you're familiar with this syntax of Java:
Copy code
  1. width>>1
or is it the first time you see anything as fancy as << and >> ?  
okay, 
yes it's the first time hat I see << or >> in processing code. 

thanks
" what is the *type* of an object ?"
It is just the class of the object. The type of a string is String, the type of a Processing vector is PVector, of its images is PImage, and so on.