Monday, November 19, 2012

Compare performace of String and StringBuilder


As we know java.lang.String is an immutable class. When we want to combine Strings, a lot of new Strings will be created before we get the last result. In some case as reading long text files or retrieving and concatenating big text fields from DB, we should consider to use StringBuilder instead of String. We will see how we could improve performance.

String – an immutable class

Immutable classes offer safe threads when we use them. However, there is a disadvantage of this type of classes is the number of existing objects. Every time we invoke methods to change states of immutable objects, we truly create new objects. Let we see an example:
          String message = "Java";
          message += " is a programming";
          message += "language.";
And we will have message = “Java is a programming language.”. The question is: How many String objects do we have after running this code? Three? Or four? The answer is five Strings: 3 obviously Strings “Java”, “ is a programming”, and “ language”; the result String “Java is a programming language.”; and another one is “Java is a programming”. The “+” operation or the concat() method of String does copy contents of original Strings to make a new String.
When the frequency to combine Strings is large, we will get abysmal performance.
StringBuilder is a mutable sequence of characters. StringBuilder is not synchronized as StringBuffer. The main operations of StringBuilder are convert() and append(). We should use StringBuilder when we need to concatenate Strings.

Compare performance by using String and StringBuilder

My computer uses Window 7 with Core i3 2.27GHz CPU and 4Gb Ram. I downloaded from the Internet one text file having 10800 lines. We will see the simple code to read this text file:

public class Test {
     public static void main(String[] args) {
          long start = System.currentTimeMillis();
          readFile("sample.txt");
          long stop = System.currentTimeMillis();
          System.out.println("Running time: " + (stop - start) + " ms");
     }

     public static String readFile(String filename) {
          String content = "";
          try {
               File file = new File(filename);
              FileReader fr;
              fr = new FileReader(file);
              BufferedReader br = new BufferedReader(fr);
              String line = "";
              while ((line = br.readLine()) != null) {
                   content += line;
              }
              br.close();
          } catch (FileNotFoundException e) {
              e.printStackTrace();
          } catch (IOException e) {
              e.printStackTrace();
          }
          return content;
     }
}
When I run this code on my laptop, the output was “Running time: 16967 ms”, near by 17 seconds. Now let we change a bit to use StringBuilder:

public class Test {
     public static void main(String[] args) {
          long start = System.currentTimeMillis();
          readFile("sample.txt");
          long stop = System.currentTimeMillis();
          System.out.println("Running time: " + (stop - start) + " ms");
     }

     public static String readFile(String filename) {
          StringBuilder content = new StringBuilder();
          try {
              File file = new File(filename);
              FileReader fr;
              fr = new FileReader(file);
              BufferedReader br = new BufferedReader(fr);
              String line = "";
              while ((line = br.readLine()) != null) {
                   content.append(line);
              }
              br.close();
          } catch (FileNotFoundException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          } catch (IOException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }

          return content.toString();
     }
}
Running this code, I got the output: “Running time: 24 ms”, faster than 700 times! Therefore, we easy decide what we should use on cases like this.

Saturday, November 17, 2012

Eclipse Working Set


Eclipse is a popular IDE for programming. We have known conveniences and utilities of this IDE. This article will show how we work with Eclipse Working Set.

What is Working Sets?

Working sets group elements for display in views or for operations on a set of elements. (Eclipse Documentation)
Eclipse allows programmers create or import plug-ins to their projects. Big projects have tens, or hundreds different plug-ins. However, we do not always work all with them at one time. Plug-ins could be grouped by purposes, tasks on projects, for examples, database plug-ins, GUI plug-ins, etc. Working Sets will help us to select and display whatever plug-ins that we want without affect to the whole system.

Create a working set

Create a working set on Eclipse is pretty easy. Assume that we have some plug-in displaying on the Package Explorer.
Step 1: Click on the small downward triangle (View Menu) and click Select Working Set.


Figure 1: List of project

Step 2: Click the New button to create a new Working Set if you do not have. In case that you already have working set, you could choose them on this step and hit OK.


Figure 2: Create a new working set

Step 3: There are several types of working sets like Resources, Breakpoint, Java …Here we choose Java and hit Next.


Figure 3: Choose a type for new working set

Step 4: Firstly, we type a name for new working set, and then we select plug-ins that we want to move from Workspace Contents to Working set content. Finally, hit Finish.


Figure 4: Select projects/plug-ins

Step 5: Select our new working set and hit OK. You could choose more than one working set.


Figure 5: Select working sets

When we finish, we just see what projects or plug-ins on chosen working sets. Using working sets do not restrict resources of the whole system. It is just the way to limit views on the Package Explorer. We still could use Ctrl + Shift + R or whatever to open other classes or resources.

A convenient way to override methods


We use @Override annotations to declare for overriding methods on sub classes. Normally, we need a new class inherit from interfaces or super classes. However, in some cases, we just want to change only one method one time, there is a better and more convenient way to do it than creation a new class.

The @Override annotation

It is not required to use this annotation for overriding methods. Your code is still fine without it (if you implement right).

class MyTextField extends JTextField {
     public String getSelectedText() {
          return super.getSelectedText().toUpperCase();
     }
}

This code is compiled successful. So why do we need the @Override annotation? It guarantees that you override on the right way. Programmers are also human who could not avoid some typing mistakes. For the example above, what will happen if we type getSelectedText to become getSelectText or getSelectionText?  If we type wrong, when a MyTextField object invokes getSelectedText() method, the result is the same with getSelectedText() of JTextField. The @Override annotation helps us to avoid this problem. It will check overriding methods with overridden methods. If they do not match, it will be a compile time error. It is much better a runtime error or even it is more dangerous and difficult to find out if it works fine but wrong results when we do not use @Override.

class MyTextField extends JTextField {
     @Override
     public String getSelectedText() {
          return super.getSelectedText().toUpperCase();
     }
}

When we use @Override, if we type getSelectionText, IDE will show an error at the line of declare method.

A convenient way to override methods

In the situation we just want to change only one method from a class on the specific case, it is not a good way if we create a new class extending that class. We could create an instance with hot-overriding way.
Normally, we often do like this when we want to implement interfaces. The common examples are *Listener interfaces. (Java Swing, Android, etc). When we want to add a listener for a button, or listView, we could add a new instance of interfaces. 


          JButton bOk = new JButton();
          bOk.addActionListener(new ActionListener() {
              @Override
              public void actionPerformed(ActionEvent arg0) {
                   // TODO Auto-generated method stub
              }
          });

The interesting thing is there are not too many people realize that we also could do it with classes. For instance, if we just want to create only one JTextField having a new getSelectedText(), we could do:

          JTextField textField = new JTextField(){
              @Override
              public String getSelectedText() {
                   return super.getSelectedText().toUpperCase();
              }
          };

The textField variable referees to a new JTextField which has only one change with the original. Obviously, we do not to create a new class and we could easily reduce the complexity of our code. This convenient way is more suitable for classes including so many methods and sometimes we just want to change one of them.

Friday, November 16, 2012

Overriding equals() and hashCode() on the right way.


Comparison Java objects

We know that there are two basic ways to compare Java objects: use the “==” operation and the equals() method.
Assume that we have a class Customer as below:

class Customer {
     private short year;
     private String name;

     public Customer(short year, String name) {
          super();
          this.year = year;
          this.name = name;
     }

     public short getYear() {
          return year;
     }

     public String getName() {
          return name;
     }
    
     // Add more code here
}
The “==” operation
The result of this operation is true when two variables refer to exactly on object. If we write and run the code as below on the main() method, we will see that the results are false and true:

     public static void main(String[] args) {
          Customer c1 = new Customer((short) 1985, "Java85");
          Customer c2 = new Customer((short) 1985, "Java85");
          Customer c3 = c2;
          System.out.println(c1 == c2);// Line 1
          System.out.println(c3 == c2);// Line 2
     }

Here c1 and c2 variables refer two different objects although the attributes are the same values. Otherwise, c2 and c2 variables refer to the second object created, so c3 == c3 returns true.
The equals() method
The equals() method is used when we want to compare different objects based on their attributes. For example in the real life, if we see two cubes having the same size and color on each sides, we could say that they equal.
Each object, when it is created, will inheritance the equals() method of java.lang.Object. On the default implementation, the equals() method just compare two objects by the “==” operation. Therefore, if we change Line 1 and Line 2 on the main() method to become:

          System.out.println(c1.equals(c2));// Line 1
          System.out.println(c3.equals(c2));// Line 2

the results are also false and true. In this case, we want that c1.equals(c2) returns true because their attributes are the same values. To do it, we need to override the equals() method. We should compare attributes that we think that they are important and necessary to compare two objects. For our example, we will compare year and name attributes of Customer class. Here is one way to override the equals() method:

     @Override
     public boolean equals(Object obj) {
          if (obj == this) {
              return true;
          }
          if (obj instanceof Customer) {
              Customer c = (Customer) obj;
              if (c.getName().equals(name) && c.getYear() == year)
                   return true;
          }
          return false;
     }

We add this code after the commend line // Add more code here on the Customer code. After that, if you run again the main() method, you will have true and true on your output.
Until here, it is enough if you just want to compare values of objects. You also could use with the contains() method of java.util.List.

          List<Customer> list = new ArrayList<Customer>();
          list.add(c1);
          System.out.println(list.contains(c1));
          System.out.println(list.contains(c2));

Execute the code, the result should be true and true . It is fine.
However, it is not enough to work with java.util.Set and java.util.Map. We could se this code:

          Map<Customer, Integer> map = new HashMap<Customer, Integer>();
          map.put(c1, 2012);
          System.out.println(map.get(c1));
          System.out.println(map.get(c2));

Running the code above, we want to see 2012 and 2012 on the result view, but the real result are 2012 and null. We look more on the example for using java.util.Set:

          Set<Customer> set = new HashSet<Customer>();
          set.add(c1);
          set.add(c2);
          System.out.println(set.size());

The same with the code for java.util.Map, this code you may want to see the size of that set is 1 because c1 equals to c2, but the real size is 2.
What is going wrong here? It is because java.util.Map and java.util.Set use hash code values of objects to compare them. To get exactly what we want, we must override the hashCode() method for Customer class.

An example for the hashCode() method

We could add the overriding code for the hastCode() method for Customer class as below:

     @Override
     public int hashCode() {
          return name.hashCode() + year;
     }

Then we run the code examples for java.util.Map and java.util.Set, we will see the results now are 2012 and 2012 for the java.util.Map example; and 1 for the java.util.Set example.
However, it is not a right way to override the hashCode() method though it is simple and easy to understand. We should override it on the way mentioned on the Effective Java ver.2 book of Joshua Bloch.

The way to override hashCode()

Follow that recommendation, we will override it by these steps:

  1. Declare a constant, for instance, int hashCode = 85;
  2. For each significant (important and necessary) attribute, we do:
        a. Compute the hashCode fc for the field f:

  • .If f is a boolean: fc = f ? 1: 0
  • .If f is a byte, short, char or int: fc = (int) f
  • .If f is a long: fc = (int) (f ^ (f>>>32))
  • .If f is a float: fc = Float.floatToIntBits(f)
  • .If f is a double: fc = Double.doubleToLongBits(f). And then calculate hashCode for fc as a long type.
  • .If f is an array, calculate for each element as a separate field.
  • .If f is an object, fc = f.hashCode()
        b. Combine fc with hashCode: hashCode = 31 * hashCode + c;

     3.   Return hashCode.

Some notes:

  • You could ignore insignificant fields.
  • The first value hastCode = 85 is arbitrary.
  • The number 31 on the step 2b could change, but it is better if it is a prime number. The value 31 is a good choice for performance when 31 * i = (i << 5) – i.
Now we come back to Customer class. We could override the hashCode() in the effective way:

     @Override
     public int hashCode() {
          int hashCode = 85;
          hashCode = 31 * hashCode + year;// year is an int
          hashCode = 31 * hashCode + name.hashCode();// name is an object (String)
          return hashCode;
     }

Now it is fine.

Reference

Effective Java ver.2 - Joshua Bloch

Thursday, November 15, 2012

Using TeXlipse to work with Latex



General

When I first time wrote my paper, I spent some hours to be familiar with Latex. My friend suggested me to look into TeXlipse and I found that it is easier for a Java programmer as me who have used Eclipse for long time. This article will show you how to setup and prepare to use TeXlipse with Eclipse. Moreover, I will show some very principle syntaxes to write on Latex.

Software

Everything I need is:

After downloading MiKTex, you install it to your system. For instance, on my computer, I install it on C:\Program Files\MiKTeX 2.9 (MIKTEX_HOME). We do not need to add any environment variables to our system.
To install TeXlipse, we could download from the Marketplaces or install it as new software (From Help menu of Eclipse).


Figure 1: Install TeXlipse from the Yoxos Marketplace.
(You should restart Eclipse after installing TeXlipse.)

Configuration

The next step is to configure Eclipse to work with TeXlipse: Builder Settings (find paths to MiKTex) and Viewer Setting (find paths to Pdf readers).

Builder Settings

We open menu Window à Preferences, expand Texlipse category and choose Builder Settings.
Here you click the Browse button to find the bin directory of MiKTex. It should be MIKTEX_HOME\miktex\bin. After that, Eclipse will map automatically programs’ paths as picture below:

Figure 2: Builder Settings

Viewer Settings

This configuration is to map a (or many) pdf reader tool with MiKTex. Click Viewer Settings of Texlipse, then remove all default viewer configurations because I do not have any tools like that. Click the new button to add Foxit Reader configuration. The viewer configuration panel will be displayed:


Figure 3: Add Forxit Reader configuration.

What we need to do is type a viewer name and browse to the installed location. We will have result after hitting the OK button:

Figure 4: Viewer Settings.
Hit OK to finish configuration step.

Demo

To easy work, we change perspectives to Latex. Click File à New à LaTeX Project:

Figure 5: Create LaTex Project

After that, we type a name for our project. The important option is output format. We change from default to pdf and build commands will be changed to pdflatex.exe (on Window). You could change templates on the list box and hit Next:

Figure 6: Choose output formats and tempaltes.

The last step for the project creation is to type names for output file and main tex file. Then, hit Finish:
Figure 7: Set output file name.

Eclipse will run and there are some logs generated on the Console view. If there is no error (suppose not if you configuration succeed), the project will have a structure as below (including a pdf file):

Figure 8: The Latex project structure on Eclipse.

Now you can happily work with Latex. Every time you change the main tex file (demo.tex) and save it, the pdf file (New paper.pdf) will be deleted and regenerated. In case you are opening the pdf file and you try to save the tex file, Eclipse will have an error. Therefore, make sure that there is no application opening your pdf file when you want to modify your tex file.

Some principle syntax of Latex

Comment

% The percent sign (%) is for comments.

Heading

\section{Big Heading}
\subsection{Small Heading}
Figure 9: Headings

Item

\begin{enumerate} % For oder by number
     \item
          Number one
     \item
          Number two
     \begin{itemize} % For order by bullets
          \item
              Bullet one
          \item
          Bullet two
     \end{itemize}
     \item
          Number three
     \begin{description} % Description keywords
          \item[Latex]
              It is great tool for writing papers.
          \item[Eclipse]
              It is powerful tool for developers.
     \end{description}
\end{enumerate}

Figure 10: Items

Some text sizes

\emph{Italic}
\textbf{Bold}
\tiny{Tiny}
\scriptsize{Scriptsize}
\footnotesize{footnotesize}
\small{small}
\normalsize{normalsize}
\large{large}
\Large{Large}
\LARGE{LARGE}
\huge{huge}
\Huge{Huge}
\textup{TextUp}
\textit{textit}
\textsl{textsl}
\textsc{textsc}
\textmd{textmd}
\textbf{textbf}

Figure 11: Text sizes

Font families

\textrm{Roman family}\\  
\rmfamily{Roman family}\\
\textsf {Sans serif family}  \\
\sffamily  {Sans serif family}  \\


Figure 12: Font families

References

Here you could find more Latex syntaxes: http://www.maths.tcd.ie/~dwilkins/LaTeXPrimer/