Monday, September 19, 2011

Difference between String and StringBuffer/StringBuilder in Java


Well, the most important difference between String and StringBuffer/StringBuilder in java is that String object is immutable whereas StringBuffer/StringBuilder objects are mutable.
By immutable, we mean that the value stored in the String object cannot be changed. Then the next question that comes to our mind is “If String is immutable then how am I able to change the contents of the object whenever I wish to?” . Well, to be precise it’s not the same String object that reflects the changes you do. Internally a new String object is created to do the changes.
So suppose you declare a String object:
String myString = “Hello”;
Next, you want to append “Guest” to the same String. What do you do?
myString = myString + ” Guest”;
When you print the contents of myString the output will be “Hello Guest”. Although we made use of the same object(myString), internally a new object was created in the process. So, if you were to do some string operation involving an append or trim or some other method call to modify your string object, you would really be creating those many new objects of class String.
Now isn’t that a performance issue?
Yes, it definitely is.
Then how do you make your string operations efficient?
By using StringBuffer or StringBuilder.
How would that help?
Well, since StringBuffer/StringBuilder objects are mutable, we can make changes to the value stored in the object. What this effectively means is that string operations such as append would be more efficient if performed using StringBuffer/StringBuilder objects than String objects.
Finally, whats the difference between StringBuffer and StringBuilder?
StringBuffer and StringBuilder have the same methods with one difference and that’s of synchronization. StringBuffer is synchronized( which means it is thread safe and hence you can use it when you implement threads for your methods) whereas StringBuilder is not synchronized( which implies it isn’t thread safe).
So, if you aren’t going to use threading then use the StringBuilder class as it’ll be more efficient than StringBuffer due to the absence of synchronization.
Incase you do not know – Here’s how you use StringBuilder
A simple Example to demonstrate that String object is Immutable
Incase you still have any doubts regarding String or StringBuilder then do leave a comment. I’ll be more than eager to help you out.
Note: StringBuilder was introduced in Java 1.5 (so if you happen to use versions 1.4 or below you’ll have to use StringBuffer)

Java String Concatenation

ref:http://javapapers.com/core-java/java-string-concatenation/

You have been told many times, don’t use + (java plus operator) to concatenate Strings. We all know that it is not good for performance. Have you researched it? Do you know what is happening behind the hood? Lets explore all about String concatenation now.
In the initial ages of java around jdk 1.2 every body used + to concatenate two String literals. When I say literal I mean it. Strings are immutable. That is, a String cannot be modified. Then what happens when we do
String fruit = "Apple"; fruit = fruit + "World";
In the above java code snippet for String concatenation, it looks like the String is modified. It is not happening. Until JDK 1.4 StringBuffer is used internally and from JDK 1.5 StringBuilder is used to concatenate. After concatenation the resultant StringBuffer or StringBuilder is changed to String.
When java experts say, “don’t use + but use StringBuffer”. If + is going to use StringBuffer internally what big difference it is going to make in String concatenation? Look at the following example. I have used both + and StringBuffer as two different cases. In case 1, I am just using + to concatenate. In case 2, I am changing the String to StringBuffer and then doing the concatenation. Then finally changing it back to String. I used a timer to record the time taken for an example String concatenation.
Look at the output (if you run this java program the result numbers might slightly vary based on your hardware / software configuration). The difference between the two cases is astonishing.
My argument is, if + is using StringBuffer internally for concatenation, then why is this huge difference in time? Let me explain that, when a + is used for concatenation see how many steps are involved:
  1. A StringBuffer object is created
  2. string1 is copied to the newly created StringBuffer object
  3. The “*” is appended to the StringBuffer (concatenation)
  4. The result is converted to back to a String object.
  5. The string1 reference is made to point at that new String.
  6. The old String that string1 previously referenced is then made null.
Hope you understand the serious performance issues and why it is important to use StringBuffer or StringBuilder (from java 1.5) to concatenate Strings.
Therefore you can see initially it was +, then StringBuffer came and now StringBuilder. Surely Java is improving release by release!

Example Java Source Code For String Concatenation

class Clock {
 
  private final long startTime;
 
  public Clock() {
    startTime = System.currentTimeMillis();
  }
 
  public long getElapsedTime() {
    return System.currentTimeMillis() - startTime;
  }
}
 
public class StringConcatenationExample {
 
  static final int N = 47500;
 
  public static void main(String args[]) {
 
    Clock clock = new Clock();
 
    //String to be used for concatenation
    String string1 = "";
    for (int i = 1; i <= N; i++) {
 
      //String concatenation using +
      string1 = string1 + "*";
    }
    //Recording the time taken to concatenate
    System.out.println("Using + Elapsed time: " + clock.getElapsedTime());
 
    clock = new Clock();
    StringBuffer stringBuffer = new StringBuffer();
    for (int i = 1; i <= N; i++) {
 
      //String concatenation using StringBuffer
      stringBuffer.append("*");
    }
    String string2 = stringBuffer.toString();
    System.out.println("Using StringBuffer Elapsed time: " + clock.getElapsedTime());
 
  }
}

Output For The Above Example Program For String Concatenation

Using + Elapsed time: 3687
Using StringBuffer Elapsed time: 16

Very good blog for JAVA --http://javapapers.com/


Tuesday, September 13, 2011

Fibonacci series in JAVA


*************************************************************************
 *  Compilation:  javac Fibonacci.java
 *  Execution:    java Fibonacci N
 *
 *  Computes and prints the first N Fibonacci numbers.
 *
 *  WARNING:  this program is spectacularly inefficient and is meant
 *            to illustrate a performance bug, e.g., set N = 45.
 *
 *
 *   % java Fibonacci 7
 *   1: 1
 *   2: 1
 *   3: 2
 *   4: 3
 *   5: 5
 *   6: 8
 *   7: 13
 *
 *   Remarks
 *   -------
 *    - The 93rd Fibonacci number would overflow a long, but this
 *      will take so long to compute with this function that we
 *      don't bother to check for overflow.
 *
 *************************************************************************/

public class Fibonacci {
    public static long fib(int n) {
        if (n <= 1) return n;
        else return fib(n-1) + fib(n-2);
    }

    public static void main(String[] args) {
        int N = Integer.parseInt(args[0]);
        for (int i = 1; i <= N; i++)
            System.out.println(i + ": " + fib(i));
    }

}
*************************************************************************
 *  Compilation:  javac Fibonacci.java
 *  Execution:    java Fibonacci N
 *
 *  Computes and prints the first N Fibonacci numbers.
 *
 *  WARNING:  this program is spectacularly inefficient and is meant
 *            to illustrate a performance bug, e.g., set N = 45.
 *
 *
 *   % java Fibonacci 7
 *   1: 1
 *   2: 1
 *   3: 2
 *   4: 3
 *   5: 5
 *   6: 8
 *   7: 13
 *
 *   Remarks
 *   -------
 *    - The 93rd Fibonacci number would overflow a long, but this
 *      will take so long to compute with this function that we
 *      don't bother to check for overflow.
 *
 *************************************************************************/

public class Fibonacci {
    public static long fib(int n) {
        if (n <= 1) return n;
        else return fib(n-1) + fib(n-2);
    }

    public static void main(String[] args) {
        int N = Integer.parseInt(args[0]);
        for (int i = 1; i <= N; i++)
            System.out.println(i + ": " + fib(i));
    }

}