Tre e mezzo [JJRumi’s blog]

September 20th, 2006

Java - Instantiating an object dynamically

Posted by jjrumi in Java, Tips

If we ever need to instantiate a bunch of objects, and the order of instantiation needs to be set dynamically, we can take a good use of the class Class and its method forName which receives an String and returns a Class.
For example:

Class i = Class.forName(”java.lang.String”);
String x = (String)i.newInstance();

This would create an String’s instance in x.

But there’s more, you can use this with the Constructor class.

Let’s suppose we have two objects (A,B) implementing an interface like this:

interface IFigure{
  public void setName(String name);
}
class A implements IFigure{
  int idx;
  String name;

  public A(){ idx=20; }
  public A(int i){ idx=i; }
  public String toString(){return “Obj_A(”+idx+”): “+this.name;}
}

class B implements IFigure{
 int idx;
 String name;

 public B(){ idx=10; }
 public B(int i){ idx= (i>0) ? (i*3) : 0; //if i>0 then idx=i*3 else i=0 }
 public void setName(String name){this.name = name;}
 public String toString(){return “Obj_B(”+idx+”): “+this.name;}
}

and we want to instantiate them, we can use this:

//The classical way:
A cA = new A();
cA.setName(”Manolo”);
System.out.println(cA);

//A dynamic way:
try{
  Class generic = Class.forName(”A”);
  Constructor constructor[] = generic.getDeclaredConstructors();

  //Careful with the index of the array!!!!
  IFigure figObj = (IFigure) constructor[1].newInstance(new Object[0]); //equals new A();

  figObj.setName(”Manolo”);

  System.out.println(”A dynamic way: \n”+figObj);
}catch(Exception e){
  e.printStackTrace();
}

In the last example, I’ve used the method getDeclaredConstructors() which returns an array with all the declared constructors of the class without an order.
Because this is very annoying, we can use instead:

Constructor c = generic.getConstructor(new Class[]{int.class})

where we explicitly indicate which constructor we want to use.

Here is a whole example:

/**
* @author Juan Luis Jiménez Rumí (www.jjrumi.com/blog)
*
*/

import java.lang.*;
import java.lang.reflect.Constructor;

interface IFigure{
  public void setName(String name);
}

class A implements IFigure{
  int idx;
  String name;
  public A(){ idx=-999; }
  public A(int i){ idx=i; }
  public void setName(String name){ this.name = name; }
  public String toString() {return “Name_A: “+name+”. Idx: “+idx;}
}

class B implements IFigure{
  int idx;
  String name;
  public B(){ idx=-999; }
  public B(int i){
    idx= (i>0) ? (i*3) : 0; //if i>0 then idx=i*3 else i=0
  }
  public void setName(String name){ this.name = name; }
  public String toString() {return “Name_B: “+name+”. Idx: “+idx;}
}

public class test{

  String ArrayObjects[] = {”A”,”B”,”C”};

  public test(){
    IFigure figObj = null;
    Constructor constructor[] = null;
    Class generic =null;

    int flag=2;
    switch(flag){
      case 1:
        //The classical way:
        A cA = new A();
        cA.setName(”Manolo”);

        //A dynamic way (with same result):
        try{
          generic = Class.forName(ArrayObjects[0]);
          constructor = generic.getDeclaredConstructors();
          figObj = (IFigure) constructor[1].newInstance(new Object[0]); //equals: new A();
          figObj.setName(”Manolo”);
          System.out.println(”A classical way: \n”+cA+”\n”);
          System.out.println(”A dynamic way: \n”+figObj);
        }catch(Exception e){
          e.printStackTrace();
        }
      break;

      case 2:
        //The classical way:
        B cB = new B(23);
        cB.setName(”Manolo”);

        //A dynamic way (with same result):
        try{
          generic = Class.forName(ArrayObjects[1]);
          Constructor c = generic.getConstructor(new Class[]{int.class});
          //equals new B(23);
          figObj = (IFigure) c.newInstance(new Object[]{new Integer(23)});
          figObj.setName(”Manolo”);
          System.out.println(”A classical way: \n”+cB+”\n”);
          System.out.println(”A dynamic way: \n”+figObj);
        }catch(Exception e){
          e.printStackTrace();
        }
        break;
    }
  }

  public static void main(String args[]){
    try{
      //Just instantiating an object from the java.lang.String class and using its *default* constructor.
      Class i = Class.forName(”java.lang.String”);
      String x = (String)i.newInstance();
      x += “some text”;
      System.out.println(”First Example: “+x+”\n———-\n”);

      test t = new test();
    }catch(Exception e){
      e.printStackTrace();
    }
  }
}

Be mad!

September 16th, 2006

Java Sorting Arrays

Posted by jjrumi in Java, Tips

The Java API includes a prefabricated method for sorting arrays. According to the official documentation, this method is a tuned quicksort, so we don’t need to write one.One example:

Long longArray[] = new Long[10];
for(int i=0; i<longArray.length; i++){
    //just a random number between 0 - 9
    longArray[i] = new Long((new Double(Math.random()*i)).longValue());
}

Arrays.sort(longArray);

for(int i=0; i<longArray.length; i++){
   System.out.print(longArray[i].longValue()+”-”);

–> This will output a list of numbers sorted in an Ascending way, (like 0,1,2,3,4…).

If we want to sort it in a reverse order (Descending), we should use: Arrays.sort(longArray,java.util.Collections.reverseOrder());

That simple.

But it isn’t the most interesting part.
We can sort objects according to some of its attributes.
To sort objects, those objects must implements the Comparable interface. For example:


//Declaring the object
class IndexedFreq implements Comparable{
   public int idx;
   public int freq;

   public IndexedFreq(int idx, int freq){
      this idx = idx;
      this.freq = freq;
   }

   public int compareTo(Object obj){
      IndexedFreq idxfreq2 = (IndexedFreq )obj; //We receive the object to compare
      int f1 = freq; //and we can access to the second object which is compared
      int f2 = idxfreq2.freq

      //Here we decide which object must come first
      if(f1<f2){
         return -1;
      }else if(f2>f1){
         return 1;
      }
      return 0; //the freqs are equal
   }
}

//Using the object
public class UseIndexedFreq{
   public static void main(String args[]){
   IndexedFreq idxFreqArray[] = new IndexedFreq[10];
   for(int i=0; i<idxFreqArray.length; i++){
      idxFreqArray.idx = i;
      idxFreqArray.freq = (new Double(Math.random()*i)).intValue();
   }

   Arrays.sort(idxFreqArray,java.util.Collections.reverseOrder());
}

In the last example I’ve created an array of IndexedFreq objects, initializing them with an index (idx) and a random frequency (freq)
As shown above, the Arrays.sort(idxFreqArray,java.util.Collections.reverseOrder()); method will sort the array, in this case according to the freq value, in a Descending order.

Note that we can do the public int compareTo(Object obj) method as complex as we like. For example we could use a new attribute in the object to define if this object must have a freq=0 so it will be allocated at the begining/end of the array (depending of the order of the sort).


Creative Commons License
This work is licensed under a Creative Commons Attribution 2.5 License.