Home | JSP | EJB | JDBC | Java Servlets | WAP  | Free JSP Hosting  | Spring Framework | Web Services | BioInformatics | Java Server Faces | Jboss 3.0 tutorial | Hibernate 3.0 | XML

Tutorial Categories: Ajax | Articles | JSP | Bioinformatics | Database | Free Books | Hibernate | J2EE | J2ME | Java | JavaScript | JDBC | JMS | Linux | MS Technology | PHP | RMI | Web-Services | Servlets | Struts | UML


 

Search Host

Monthly Fee($)
Disk Space (MB)
Register With us for Newsletter!
Visit Forum! Post Questions!
Jobs At RoseIndia.net!

Have tutorials?
Add your tutorial to our Java Resource and get tons of hits.

We offer free hosting for your tutorials. and exposure for thousands of readers. drop a mail
roseindia_net@yahoo.com
 
   

Tutorials

Java Server Pages

JAXB

Java Beans

JDBC

MySQL

Java Servlets

Struts

Bioinformatics

Java Code Examples

Interview Questions

 
Join For Newsletter

Powered by groups.yahoo.com
Visit Group! Post Questions!

Web Promotion

Web Submission

Submit Sites

Manual Submission?

Web Promotion Guide

Hosting Companies

Web Hosting Guide

Web Hosting

Linux

Beginner Guide to Linux Server

Frameworks

Persistence Framework

Web Frameworks

Free EAI Tools

Web Servers

Aspect Oriented Programming

Free Proxy Servers

Softwares

Adware & Spyware Remover

Open Source Softwares

Autoboxing Yourself in JDK 1.5

       

2004-06-22 The Java Specialists' Newsletter [Issue 090] - Autoboxing Yourself in JDK 1.5

Author: Dr. Heinz M. Kabutz

If you are reading this, and have not subscribed, please consider doing it now by going to our subscribe page. You can subscribe either via email or RSS.


Welcome to the 90th edition of The Java(tm) Specialists' Newsletter. I would like to thank all my loyal readers for spreading the word about this newsletter. Today is a special day for my son Maxi, as he celebrates his 6th birthday. Kids are a great way of reminding you how old you are getting... Before I know it, he'll be asking me to buy him a car...

The Psychology of Computer Programming: A great book by Gerald Weinberg (also wrote Secrets of Consulting, reviewed in TJSN 048) This is the type of book that you can pick up, read three pages, have a few laughs, and then put it down again.

In his book, Weinberg assumes that programmers are of above-average intelligence. The first edition of the book was written in the year I was born (1971). At the time of writing, before the invention of contact lenses, most programmers really did look like archetypal nerds. Popular thought was that you had to be good at Mathematics to become a programmer. Since it takes a bit of intelligence to be good at Maths (and a lot of hard work), the less-brainy kids stayed away from computer programming. My, how the industry has changed!

Today, I cringe when people ask me what I do for a living. My favourite answer is: "I stand in front of crowds and tell jokes." That sounds far more interesting than: "I go to corporations and teach their programmers how to be more effective in Java and Object Orientation." As soon as I mention that my job has anything to do with computers, the reply I get every time is: "Oh yes, my uncle/brother/sister/father/son/mother/auntie is an absolute genius with computers - he even did an MCS-whats-the-name."

This is a classic book that every programmer and project manager should read. You can probably pick up a dusty copy of the original 1971 print in your computer science department library.

Autoboxing Yourself in JDK 1.5

From the old (1971) to the new (2004).

On my last Java Course in Pretoria (South Africa), I demonstrated to my class how autoboxing worked. Our experiments showed that autoboxing can be inefficient. As nice as the feature is, it is also rather dangerous. Java learners could use autoboxing by mistake, negatively affecting performance.

However, before I delve into autoboxing, I would like to write something about the new for construct.

The New for Construct

About two-and-a-half years ago, I complained bitterly in TJSN 040 about the Iterator idiom. I felt that using a for or a while loop, together with a typecast, tended to make our code look ugly. The new for construct in JDK 1.5 finally addresses my complaint. This is how you can use it in your code:

import java.util.*;

public class NewFor {
  public static void main(String[] args) {
    // we can use type-safe collections...
    Collection<String> names = new ArrayList<String>();
    names.add("Maxi");
    names.add("Connie");
    names.add("Helene");
    names.add("Heinz");
    //names.add(new Integer(42)); -- does not compile!
    // look at the new for construct:
    for (String name : names) {
      System.out.println("name = " + name);
    }
  }
}
  

Endorsement: After having spent several years using different IDEs and editors (JBuilder, VI, Notepad, Eclipse), I have finally come to rest. Last year I took IntelliJ IDEA for a spin, and have not looked back since. It just always does exactly what I expect it to do. I can do almost anything with keystrokes, instead of moving my hands off the keyboard onto my mouse. In addition, it supports all of the JDK 1.5 features already, even though that version of the JDK is only in beta. Do yourself a favour, take the latest early access version for a test run: IntelliJ EAP. [No, I am not being paid for endorsing IntelliJ, and I understand completely if you prefer Eclipse.]

We can combine autoboxing with generics. (Autoboxing is the process of converting primitives to objects and vice-versa, automatically). My example code in newsletter # 40 could have been written more elegantly like so:

  public void showAging(Collection<Integer> ages) {
    for(int age : ages) {
      System.out.println("Now you're " + age +
        ", in 3 years time, you'll be " + (age + 3));
    }
  }
  

I discovered by accident that you can also use this new for construct with arrays:

public class NewForArrays {
  public static void main(String[] args) {
    String[] names = {"Maxi", "Connie", "Helene", "Heinz"};
    for (String name : names) {
      System.out.println("name = " + name);
    }
  }
}
  

Isn't that beautiful? At long last, a consistent way of iterating through collections and arrays. This even works for arrays of primitives:

public class NewForPrimitiveArrays {
  public static void main(String[] args) {
    int[] daysPerMonth = {31,28,31,30,31,30,31,31,30,31,30,31};
    int totalDays = 0;
    for (int days : daysPerMonth) {
      totalDays += days;
    }
    System.out.println("totalDays = " + totalDays);
  }
}
  

When we decompile the class, we see the following (not too unreasonable):

public class NewForPrimitiveArrays {
  public static void main(String args[]) {
    int daysPerMonth[] = {
      31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
    };
    int totalDays = 0;
    int arr$[] = daysPerMonth;
    int len$ = arr$.length;
    for(int i$ = 0; i$ < len$; i$++) {
      int days = arr$[i$];
      totalDays += days;
    }
    System.out.println("totalDays = " + totalDays);
  }
}

A great fear of programmers is that you might use some new construct that then makes your code unacceptably slow. Here is some code that compares the performance of "old" and "new" for constructs:

import java.util.*;

public class NewForPerformance {
  public static void main(String[] args) {
    // let's look at the performance difference of for construct
    Collection<Integer> numbers = new ArrayList<Integer>(10000);
    for(int i=0;i<10000; i++) {
      // I can add an "int" to a collection of Integer, thanks
      // to the autoboxing construct shamelessly copied from C#
      numbers.add((int)Math.random());
    }
    oldFor(numbers);
    newFor(numbers);
  }
  private static void oldFor(final Collection<Integer> numbers) {
    measureIterations("oldFor", new Runnable() {
      public void run() {
        for(Iterator<Integer> it = numbers.iterator(); it.hasNext();) {
          Integer i = it.next();
        }
      }
    });
  }
  private static void newFor(final Collection<Integer> numbers) {
    measureIterations("newFor", new Runnable() {
      public void run() {
        for(Integer i : numbers);
      }
    });
  }
  private static void measureIterations(String method, Runnable r) {
    long start = System.currentTimeMillis();
    int iterations = 0;
    while(System.currentTimeMillis() - start <= 2000) {
      r.run();
      iterations++;
    }
    System.out.println(method + ": " + iterations + " in " +
        (System.currentTimeMillis()-start) + "ms");
  }
}

When I run this, I get the following output:

oldFor: 3532 in 2003ms
newFor: 3561 in 2003ms

The two methods are similar enough that we can declare that there is no difference between them. So, would you not rather use the new for construct instead of struggling with the old iterators?

Danger Lurking Below

Let us presume that armies of Java programmers will jump at the opportunity of using Generics and the new for construct. This will make arrays redundant, since autoboxing allows us to use ints with collections (note that we are adding and getting the values from the collection as the primitive data type int, but the type of object in the collection is Integer):

import java.util.*;

public class AutoBoxing {
  public static void main(String[] args) {
    Collection<Integer> values = new ArrayList<Integer>();
    for (int i=0; i<100; i++) {
      values.add(i);
    }
    for(int val : values) {
      System.out.println(val);
    }
  }
}
  

Let's see what happens when we have a collection of numbers, and we want to increment all the values:

import java.util.*;

public class AutoBoxingIncrement {
  public static void main(String[] args) {
    // we set up a Collection containing Integers and an int[]
    List<Integer> values = new ArrayList<Integer>();
    int[] valuesArray = new int[1000];
    for (int i = 0; i < 1000; i++) {
      values.add(i);
      valuesArray[i] = i;
    }

    // let's time how quickly we can increment the 1000 values
    long time = System.currentTimeMillis();
    // we must do it a few times to see the difference
    for (int j = 0; j < 100000; j++) {
      for (int i = 0; i < values.size(); i++) {
        values.set(i, values.get(i) + 1);
      }
    }
    System.out.println("autoboxing with generics took " +
        (System.currentTimeMillis() - time) + "ms");

    // now we try with an array
    time = System.currentTimeMillis();
    for (int j = 0; j < 100000; j++) {
      for (int i = 0; i < valuesArray.length; i++) {
        valuesArray[i]++;
      }
    }
    System.out.println("Using a plain array took " +
        (System.currentTimeMillis() - time) + "ms");
  }
}
  

When I run this on my little notebook, I see a huge difference in performance. The direct array method of using ints is about 20 times faster!!!

    autoboxing with generics took 9954ms
    Using a plain array took 551ms
  

Generics were extremely easy to learn, and after using them for a few hours, I did not want to go back to type-unsafe Collections. However, we have to be aware when we may be doing stupid things that could impact performance, such as autoboxing when we should not.

Kind regards

Heinz

This material from The Java(tm) Specialists' Newsletter by Maximum Solutions (South Africa). Please contact Maximum Solutions for more information.

       

Useful Links
  JDO Tutorials
  EAI Articles
  Struts Tutorials
  Java Tutorials
  Java Certification
Tell A Friend
Your Friend Name
Search Tutorials

 

 
Browse all Java Tutorials
Java JSP Struts Servlets Hibernate XML
Ajax JDBC EJB MySQL JavaScript JSF
Maven2 Tutorial JEE5 Tutorial Java Threading Tutorial Photoshop Tutorials Linux Technology
Technology Revolutions Eclipse Spring Tutorial Bioinformatics Tutorials Tools SQL
 

Home | JSP | EJB | JDBC | Java Servlets | WAP  | Free JSP Hosting  | Search Engine | News Archive | Jboss 3.0 tutorial | Free Linux CD's | Forum | Blogs

About Us | Advertising On RoseIndia.net

Send your comments, Suggestions or Queries regarding this site at roseindia_net@yahoo.com.

Copyright 2007. All rights reserved.