Friday, December 28, 2007

Closure Conversion

Closure Conversion

A closure can be assigned to a variable of compatible interface type. A compatible interface type must have a single method with a compatible return type and compatible argument types. For example:

  interface IntPlus {
    int add(int x, int y);
  }
  IntPlus plus = { int x, int y => x + y };
  

In such case, a closure is converted to an instance of anonymous class that implements the given interface:

  IntPlus plus = new IntPlus() {
    public int add(int x, int y) { return x + y; }
  };
  

Then, we call the closure by the interface method:

  int sum = plus.add(5, 6);
  

This allows us to use a closure instead of anonymous subclass of interface with a single method. For example, the closure conversion can create an instance of Runnable:

  new Thread({ => System.out.println("hi"); }).start();
  

Sometimes we can use the closure conversion even if the interface has more than one method. It is in case when all but one method are implemented in Object. The closure is then converted to a single remaining method. For example, interface Comparator contains two methods: compare() and equals(). Method equals() is in Object and so the closure is converted to method compare().

  String[] girls = { "Jane", "Eva", "Sarah", "Alice" };
  Arrays.sort(girls,
    { String s1, String s2 =>
      int r = s1.length() - s2.length(); r == 0 ? s1.compareTo(s2) : r 
    });
  

Exercises

  1. Declare interface HashCalculator.
      HashCalculator hc = 
        { String s1, String s2 => s1.hashCode() ^ s2.hashCode() };
      System.out.println(hc.hash("elephant", "giraffe"));
      
  2. Use a closure to define Comparator which sort numbers descendingly.
      Integer[] wages = { 1200, 4500, 850, 1500, 990 };
      Arrays.sort(wages,                                      );
      
  3. Sort an array of strings and count the number of comparisons.

Solutions

  interface HashCalculator {
    int hash(String s1, String s2);
  }
  
  Integer[] wages = { 1200, 4500, 850, 1500, 990 };
  Arrays.sort(wages, { Integer i, Integer j => j.compareTo(i) });
  
  String[] countries = { 
    "France", "Czech Republic", "Poland", "Hungary", "Germany" 
  };
  int c = 0;
  Arrays.sort(countries, { String s1, String s2 => c++; s1.compareTo(s2) });
  System.out.println("number of comparisons: " + c);
  

7 comments:

Anonymous said...

Wow, i think your examples are easier to follow than Neal Grafter's own. Thanks.

Vyas, Anirudh

Anonymous said...

I'm trying to rewrite:
EventQueue.invokeLater(new Runnable()
{
public void run()
{
//set some text.
}
});

As:
EventQueue.invokeLater(new Thread(
{ =>
//set some text
}
).start();
);

Running into compile time errors(after I downloaded the new prototype from javac.info), and I tried to follow your example from above. Can you spot the error please?

Zdeněk Troníček said...

EventQueue.invokeLater() takes a Runnable as argument:
EventQueue.invokeLater({ => System.out.println("hi"); });

Anonymous said...

Thanks a lot! It works :).

lwesterhoff said...

Normally adding a method to an interface is backwards compatible. With closure conversion, adding a method to an interface with a single method is no longer backwards compatible since it can break code when its used with closures.

Zdeněk Troníček said...

Perhaps I do not understand what you want to say because adding a method to an interface is NOT backward compatible.

Toko Jual Obat Kuat Alat Bantu Sex 087733776655 said...

Klik Aja Di Bawah Ini
Pemesanan: 087733776655
http://obatkuat-57.com/
Jual Obat Pembesar Penis Vigrx Plus
Alat Bantu Sex Pria Dan Wanita
Rajanya Obat Kuat Sex
Obat Perangsang Wanita, Obat Gairah Wanita
Obat Pembesar Payudara Monyok, Payudara Kencang
Alat Pembesar Payudara Montok
Alat Pembesar Penis
Alat Sex Pria Boneka Moderen
Obat Pengental Sperma
Minyak Pembesar Penis, Obat Pemanjang Penis
Obat Hernia Paling Ampuh
Obat Pelangsing Badan, Melangsingkan Tubuh
Obat Perapet Vagina
Obat Peninggi Badan, Meninggikan Bada
Obat Pembesar Pantat, Pembesar Bokong
Obat Pemerah Bibir, Pemerah Puting
Obat Pemutih Wajah Alami Tensung Cream
Obat Penggemuk Badan
Obat Penghilang Tatto Permanen Herbal Alami
Kondom Antik Pria
Rajanya Obat Kuat Pria
Alat Bantu Sex Wanita Antik
Alat Bantu Sex Pria
Obat Kuat Herbal
Vimax Obat Pembesar Alat Vital
Cara Memutihkan Selangkangan dan Ketiak


Obat Pelangsing Badan Fatloss Jimpness Beauty
Selaput Dara Perawan Buatan